一、简介

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

二、详解

1、代码

(1)slidingwindow.h

  1. #ifndef SLIDINGWINDOW_H
  2. #define SLIDINGWINDOW_H
  3. #include <QtGui>
  4. class SlidingWindow : public QWidget
  5. {
  6. Q_OBJECT
  7. public:
  8. SlidingWindow(QWidget *parent = 0);
  9. ~SlidingWindow();
  10. protected:
  11. void mousePressEvent ( QMouseEvent * event);
  12. void mouseMoveEvent(QMouseEvent *event);
  13. void mouseReleaseEvent(QMouseEvent *event);
  14. void resizeEvent(QResizeEvent *event);
  15. bool eventFilter(QObject *obj, QEvent *event);
  16. private:
  17. void setBtnPos();
  18. void setBtnIcon();
  19. private slots:
  20. void slotClickedBtn();
  21. void slotSplitterMoved(int pos, int index);
  22. private:
  23. QPoint dragPosition;
  24. bool bPressFlag;
  25. QSplitter *splitter;
  26. QFrame *contentFrame;
  27. QFrame *listFrame;
  28. QPushButton *pushButton;
  29. QIcon leftIcon;
  30. QIcon rightIcon;
  31. };
  32. #endif // SLIDINGWINDOW_H

(2)slidingwindow.cpp

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

(3)main.cpp

  1. #include "slidingwindow.h"
  2. #include <QApplication>
  3. int main(int argc, char *argv[])
  4. {
  5. QApplication a(argc, argv);
  6. SlidingWindow w;
  7. w.show();
  8. return a.exec();
  9. }

(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

Qt浅谈之四十五QSplitter实现自由伸缩滑动窗口的更多相关文章

  1. QSplitter实现自由伸缩滑动窗口部件(要在m_pSplitter中加入frame_4之前,给frame_4设置样式;之后设置无效)

    实现代码如下: #include <QSplitter> QSplitter *m_pSplitter; m_pSplitter = new QSplitter(ui->frame_ ...

  2. Qt浅谈之四十九俄罗斯方块(代码来自网络)

    一.简介 从网上下载了一个Qt实现的俄罗斯方块单机版的源码,觉得非常有意思,故以博客形式记录下来,以便慢慢来研究.在centos6.6下编译运行(注意程序运行需要读取pro目录的配置文件,若把编译目录 ...

  3. Qt浅谈之十八:GraphicsView框架事件处理(有源码下载)

    一.简介 GraphicsView支持事件传播体系结构,可以使图元在场景scene中得到提高了已被的精确交互能力.图形视图框架中的事件都是首先由视图进行接收,然后传递给场景,再由场景给相应的图形项. ...

  4. Qt浅谈之三十九圆形进度条(已经有50篇了)

    http://blog.csdn.net/taiyang1987912/article/category/2314763

  5. Qt浅谈内存泄露(总结)

    Qt浅谈内存泄露(总结) 来源 http://blog.csdn.net/taiyang1987912/article/details/29271549 一.简介 Qt内存管理机制:Qt 在内部能够维 ...

  6. Qt浅谈之总结(整理)

    Qt浅谈之总结(整理) 来源 http://blog.csdn.net/taiyang1987912/article/details/32713781 一.简介 QT的一些知识点总结,方便以后查阅. ...

  7. Qt::浅谈信号槽连接,参数在多线程中的使用

    Qt的信号槽有五种连接方式定义在enum Qt::ConnectionType,下面简单介绍 Qt::AutoConnection:自动判断连接方式,如果信号发送对象和执行槽对象在同一线程,那么等于Q ...

  8. Qt浅谈之二十App自动重启及关闭子窗口

    一.简介 最近因项目需求,Qt程序一旦检测到错误,要重新启动,自己是每次关闭主窗口的所有子窗口但有些模态框会出现问题,因此从网上总结了一些知识点,以备以后的应用. 二.详解 1.Qt结构 int ma ...

  9. Qt浅谈之二十App自动重启及关闭子窗口(六种方法)

    一.简介 最近因项目需求,Qt程序一旦检测到错误,要重新启动,自己是每次关闭主窗口的所有子窗口但有些模态框会出现问题,因此从网上总结了一些知识点,以备以后的应用. 二.详解 1.Qt结构 int ma ...

随机推荐

  1. Android中PopupWindow中有输入框时无法弹出输入法的解决办法

    PopupWindow window=new PopupWindow(view, LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT); //必须让p ...

  2. 为什么使用Redis

    原文地址:http://igoder.iteye.com/blog/1969848 先解释一下软件编程中常见的一些概念: 抽象先于具象.这个抽象并非虚无的抽象,而是指事物尚未分化为具象之前的那个前体存 ...

  3. [转]10款 Web 开发常备工具

    文章地址:https://my.oschina.net/u/2903254/blog/798135 工欲善其事,必先利其器.如今 Web 开发标准越来越高,Web 开发者也在不断寻找途径提升自己的技能 ...

  4. Codeforces Round #292 (Div. 1) - B. Drazil and Tiles

    B. Drazil and Tiles   Drazil created a following problem about putting 1 × 2 tiles into an n × m gri ...

  5. Hadoop-2.x的源码编译

    由于在Hadoop-2.x中,Apache官网上提供的都是32位版本,如果是生产环境中则需要自行编译64位,编译Hadoop-2.x版本方法如下: 安装编译源码所依赖的底层库 yum install ...

  6. Windows下oracle打补丁步骤

    1.Oracle官网下载对应的补丁文件(需要oracle支持账号才能下载) 2.设置ORACLE_HOME set oracle_home=F:\oracle\product\11.2.0\dbhom ...

  7. 关于javax.crypto.BadPaddingException: Blocktype错误的几种解决方法

    此文章转载自:http://www.myexception.cn/mobile/1259076.html 关于javax.crypto.BadPaddingException: Blocktype异常 ...

  8. Android学习【Android内核编译流程和错误笔记】

    博客:http://blog.csdn.net/muyang_ren Ubuntu14.04 LTS(要求是64位长期支持版LTS) Jdk1.8 内核:android4.0 一:jdk 1.解压jd ...

  9. Android学习之多点触摸并不神秘

    最近研究了一下多点触摸,写了个利用多点触摸来控制图片大小和单点触摸控制图片移动的程序,和大家分享分享. Android中监听触摸事件是onTouchEvent方法,它的参数为MotionEvent,下 ...

  10. 内容观察者 ContentObserver 监听短信、通话记录数据库 挂断来电

    Activity public class MainActivity extends ListActivity {     private TextView tv_info;     private  ...