Qt浅谈之四十五QSplitter实现自由伸缩滑动窗口
2016-02-22 15:50
423 查看
一、简介
最近看到一篇Qt实现伸缩滑动的窗口的文章,但其代码不完整。便在此重新书写了完整的代码,并开源出来。窗口的中央有滑动条可以动态改变子窗口的大小,隐藏的按钮可以快速伸缩子窗口。其效果图如下:
二、详解
1、代码
(1)slidingwindow.h#ifndef SLIDINGWINDOW_H #define SLIDINGWINDOW_H #include <QtGui> class SlidingWindow : public QWidget { Q_OBJECT public: SlidingWindow(QWidget *parent = 0); ~SlidingWindow(); protected: void mousePressEvent ( QMouseEvent * event); void mouseMoveEvent(QMouseEvent *event); void mouseReleaseEvent(QMouseEvent *event); void resizeEvent(QResizeEvent *event); bool eventFilter(QObject *obj, QEvent *event); private: void setBtnPos(); void setBtnIcon(); private slots: void slotClickedBtn(); void slotSplitterMoved(int pos, int index); private: QPoint dragPosition; bool bPressFlag; QSplitter *splitter; QFrame *contentFrame; QFrame *listFrame; QPushButton *pushButton; QIcon leftIcon; QIcon rightIcon; }; #endif // SLIDINGWINDOW_H(2)slidingwindow.cpp
#include "slidingwindow.h" SlidingWindow::SlidingWindow(QWidget *parent) : QWidget(parent, Qt::FramelessWindowHint) , bPressFlag(false) { resize(660, 460); splitter = new QSplitter(Qt::Horizontal, this); splitter->setHandleWidth(1); splitter->setStyleSheet("QSplitter::handle{background:#FFFFFF}"); contentFrame = new QFrame(splitter); contentFrame->setStyleSheet("background:#000000"); contentFrame->resize(475, height()); contentFrame->setMinimumWidth(405); listFrame = new QFrame(splitter); listFrame->setStyleSheet("background:#323232"); listFrame->resize(660 - 475, height()); listFrame->setMaximumWidth(660 - 405); connect(splitter, SIGNAL(splitterMoved(int,int)), this, SLOT(slotSplitterMoved(int,int))); leftIcon = QIcon(":/left.png"); rightIcon = QIcon(":/right.png"); pushButton = new QPushButton(this); pushButton->setFocusPolicy(Qt::NoFocus); pushButton->hide(); pushButton->setFixedSize(13, 42); pushButton->setIconSize(pushButton->size()); pushButton->setStyleSheet("border:none;"); pushButton->setIcon(rightIcon); pushButton->move(contentFrame->width() - pushButton->width()-2, (contentFrame->height() - pushButton->height())/2); connect(pushButton,SIGNAL(clicked()),this,SLOT(slotClickedBtn())); contentFrame->setMouseTracking(true); listFrame->setMouseTracking(true); contentFrame->installEventFilter(this); listFrame->installEventFilter(this); } SlidingWindow::~SlidingWindow() { } void SlidingWindow::resizeEvent(QResizeEvent *event) { splitter->setGeometry(0, 0, width(), height()); move((QApplication::desktop()->width() - width())/2, (QApplication::desktop()->height() - height())/2); QWidget::resizeEvent(event); } bool SlidingWindow::eventFilter(QObject *obj, QEvent *event) { if (event->type() == QEvent::MouseMove) { QMouseEvent *mouseMove = static_cast<QMouseEvent*>(event); QRect rect = pushButton->frameGeometry(); if (rect.contains(mouseMove->pos())) { pushButton->show(); } else { pushButton->hide(); } } return QWidget::eventFilter(obj, event); } void SlidingWindow::setBtnPos() { pushButton->move(contentFrame->width() - pushButton->width(), (contentFrame->height() - pushButton->height())/2); } void SlidingWindow::setBtnIcon() { if (listFrame->width() != 0) { pushButton->setIcon(rightIcon); } else { pushButton->setIcon(leftIcon); } } void SlidingWindow::slotClickedBtn() { QList <int> sizeList; sizeList.clear(); if (listFrame->width() != 0) { sizeList.append(660); sizeList.append(0); } else { sizeList.append(475); sizeList.append(660 - 475); } splitter->setSizes(sizeList); setBtnIcon(); setBtnPos(); pushButton->hide(); } void SlidingWindow::slotSplitterMoved(int pos, int index) { Q_UNUSED(pos) Q_UNUSED(index) setBtnIcon(); setBtnPos(); } void SlidingWindow::mousePressEvent ( QMouseEvent * event) { bPressFlag = true; dragPosition = event->pos(); QWidget::mousePressEvent(event); } void SlidingWindow::mouseMoveEvent(QMouseEvent *event) { if (bPressFlag) { QPoint relaPos(QCursor::pos() - dragPosition); move(relaPos); } QWidget::mouseMoveEvent(event); } void SlidingWindow::mouseReleaseEvent(QMouseEvent *event) { bPressFlag = false; QWidget::mouseReleaseEvent(event); }(3)main.cpp
#include "slidingwindow.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); SlidingWindow w; w.show(); return a.exec(); }(4)编译运行
三、总结
(1)获取位置坐标可以尝试QPoint realPos(QCursor::pos() - this->pos());,这样不用类型转换。主要设置setMouseTracking(true);才能当鼠标不点击时移动鼠标进入mouseMoveEvent事件函数。(2)源码已上传到csdn:http://download.csdn.net/detail/taiyang1987912/9439233。
(3)若有问题或建议,请留言,在此感谢!
相关文章推荐
- Linux socket 初步
- Linux Kernel 4.0 RC5 发布!
- linux lsof详解
- linux 文件权限
- Linux 执行数学运算
- 10 篇对初学者和专家都有用的 Linux 命令教程
- Linux 与 Windows 对UNICODE 的处理方式
- Ubuntu12.04下QQ完美走起啊!走起啊!有木有啊!
- 解決Linux下Android开发真机调试设备不被识别问题
- 运维入门
- 运维提升
- Linux 自检和 SystemTap
- Ubuntu Linux使用体验
- c语言实现hashmap(转载)
- Linux 信号signal处理机制
- linux下mysql添加用户
- Scientific Linux 5.5 图形安装教程
- Linux 下无损图片压缩小工具介绍