Qt浅谈之四十五QSplitter实现自由伸缩滑动窗口

一、简介

        最近看到一篇Qt实现伸缩滑动的窗口的文章,但其代码不完整。便在此重新书写了完整的代码,并开源出来。窗口的中央有滑动条可以动态改变子窗口的大小,隐藏的按钮可以快速伸缩子窗口。其效果图如下:

二、详解

1、代码

(1)slidingwindow.h

[html] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. #ifndef SLIDINGWINDOW_H  
  2. #define SLIDINGWINDOW_H  
  3.   
  4. #include <QtGui>  
  5.   
  6. class SlidingWindow : public QWidget  
  7. {  
  8.     Q_OBJECT  
  9.   
  10. public:  
  11.     SlidingWindow(QWidget *parent = 0);  
  12.     ~SlidingWindow();  
  13.   
  14. protected:  
  15.     void mousePressEvent ( QMouseEvent * event);  
  16.     void mouseMoveEvent(QMouseEvent *event);  
  17.     void mouseReleaseEvent(QMouseEvent *event);  
  18.     void resizeEvent(QResizeEvent *event);  
  19.     bool eventFilter(QObject *obj, QEvent *event);  
  20.   
  21. private:  
  22.     void setBtnPos();  
  23.     void setBtnIcon();  
  24.   
  25. private slots:  
  26.     void slotClickedBtn();  
  27.     void slotSplitterMoved(int pos, int index);  
  28.   
  29. private:  
  30.     QPoint dragPosition;  
  31.     bool bPressFlag;  
  32.     QSplitter *splitter;  
  33.     QFrame *contentFrame;  
  34.     QFrame *listFrame;  
  35.     QPushButton *pushButton;  
  36.     QIcon leftIcon;  
  37.     QIcon rightIcon;  
  38. };  
  39.   
  40. #endif // SLIDINGWINDOW_H  

(2)slidingwindow.cpp

[html] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. #include "slidingwindow.h"  
  2.   
  3. SlidingWindow::SlidingWindow(QWidget *parent)  
  4.     : QWidget(parent, Qt::FramelessWindowHint)  
  5.     , bPressFlag(false)  
  6. {  
  7.     resize(660, 460);  
  8.     splitter = new QSplitter(Qt::Horizontal, this);  
  9.     splitter->setHandleWidth(1);  
  10.     splitter->setStyleSheet("QSplitter::handle{background:#FFFFFF}");  
  11.     contentFrame = new QFrame(splitter);  
  12.     contentFrame->setStyleSheet("background:#000000");  
  13.     contentFrame->resize(475, height());  
  14.     contentFrame->setMinimumWidth(405);  
  15.     listFrame = new QFrame(splitter);  
  16.     listFrame->setStyleSheet("background:#323232");  
  17.     listFrame->resize(660 - 475, height());  
  18.     listFrame->setMaximumWidth(660 - 405);  
  19.     connect(splitter, SIGNAL(splitterMoved(int,int)), this, SLOT(slotSplitterMoved(int,int)));  
  20.   
  21.     leftIcon = QIcon(":/left.png");  
  22.     rightIcon = QIcon(":/right.png");  
  23.   
  24.     pushButton = new QPushButton(this);  
  25.     pushButton->setFocusPolicy(Qt::NoFocus);  
  26.     pushButton->hide();  
  27.     pushButton->setFixedSize(13, 42);  
  28.     pushButton->setIconSize(pushButton->size());  
  29.     pushButton->setStyleSheet("border:none;");  
  30.     pushButton->setIcon(rightIcon);  
  31.     pushButton->move(contentFrame->width() - pushButton->width()-2, (contentFrame->height() - pushButton->height())/2);  
  32.     connect(pushButton,SIGNAL(clicked()),this,SLOT(slotClickedBtn()));  
  33.   
  34.     contentFrame->setMouseTracking(true);  
  35.     listFrame->setMouseTracking(true);  
  36.     contentFrame->installEventFilter(this);  
  37.     listFrame->installEventFilter(this);  
  38. }  
  39.   
  40. SlidingWindow::~SlidingWindow()  
  41. {  
  42.   
  43. }  
  44.   
  45. void SlidingWindow::resizeEvent(QResizeEvent *event)  
  46. {  
  47.     splitter->setGeometry(0, 0, width(), height());  
  48.     move((QApplication::desktop()->width() - width())/2,  (QApplication::desktop()->height() - height())/2);  
  49.     QWidget::resizeEvent(event);  
  50. }  
  51.   
  52. bool SlidingWindow::eventFilter(QObject *obj, QEvent *event)  
  53. {  
  54.     if (event->type() == QEvent::MouseMove) {  
  55.         QMouseEvent *mouseMove = static_cast<QMouseEvent*>(event);  
  56.         QRect rect = pushButton->frameGeometry();  
  57.         if (rect.contains(mouseMove->pos())) {  
  58.             pushButton->show();  
  59.         }  
  60.         else {  
  61.             pushButton->hide();  
  62.         }  
  63.     }  
  64.     return QWidget::eventFilter(obj, event);  
  65. }  
  66.   
  67. void SlidingWindow::setBtnPos()  
  68. {  
  69.     pushButton->move(contentFrame->width() - pushButton->width(), (contentFrame->height() - pushButton->height())/2);  
  70. }  
  71.   
  72. void SlidingWindow::setBtnIcon()  
  73. {  
  74.     if (listFrame->width() != 0) {  
  75.         pushButton->setIcon(rightIcon);  
  76.     }  
  77.     else {  
  78.         pushButton->setIcon(leftIcon);  
  79.     }  
  80. }  
  81.   
  82. void SlidingWindow::slotClickedBtn()  
  83. {  
  84.     QList <int> sizeList;  
  85.     sizeList.clear();  
  86.     if (listFrame->width() != 0) {  
  87.         sizeList.append(660);  
  88.         sizeList.append(0);  
  89.     }  
  90.     else {  
  91.         sizeList.append(475);  
  92.         sizeList.append(660 - 475);  
  93.     }  
  94.     splitter->setSizes(sizeList);  
  95.   
  96.     setBtnIcon();  
  97.     setBtnPos();  
  98.     pushButton->hide();  
  99. }  
  100.   
  101. void SlidingWindow::slotSplitterMoved(int pos, int index)  
  102. {  
  103.     Q_UNUSED(pos)  
  104.     Q_UNUSED(index)  
  105.     setBtnIcon();  
  106.     setBtnPos();  
  107. }  
  108.   
  109. void SlidingWindow::mousePressEvent ( QMouseEvent * event)  
  110. {  
  111.     bPressFlag = true;  
  112.     dragPosition = event->pos();  
  113.     QWidget::mousePressEvent(event);  
  114. }  
  115.   
  116. void SlidingWindow::mouseMoveEvent(QMouseEvent *event)  
  117. {  
  118.     if (bPressFlag) {  
  119.         QPoint relaPos(QCursor::pos() - dragPosition);  
  120.         move(relaPos);  
  121.     }  
  122.     QWidget::mouseMoveEvent(event);  
  123. }  
  124.   
  125. void SlidingWindow::mouseReleaseEvent(QMouseEvent *event)  
  126. {  
  127.     bPressFlag = false;  
  128.     QWidget::mouseReleaseEvent(event);  
  129. }  

(3)main.cpp

[html] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. #include "slidingwindow.h"  
  2. #include <QApplication>  
  3.   
  4. int main(int argc, char *argv[])  
  5. {  
  6.     QApplication a(argc, argv);  
  7.     SlidingWindow w;  
  8.     w.show();  
  9.   
  10.     return a.exec();  
  11. }  

(4)编译运行

三、总结

(1)获取位置坐标可以尝试QPoint realPos(QCursor::pos() - this->pos());,这样不用类型转换。主要设置setMouseTracking(true);才能当鼠标不点击时移动鼠标进入mouseMoveEvent事件函数。
(2)源码已上传到csdn:http://download.csdn.net/detail/taiyang1987912/9439233
(3)若有问题或建议,请留言,在此感谢!

http://blog.csdn.net/taiyang1987912/article/details/50717179

原文地址:https://www.cnblogs.com/findumars/p/5782381.html