Qt浅谈之四十五QSplitter实现自由伸缩滑动窗口
一、简介
最近看到一篇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)若有问题或建议,请留言,在此感谢!
http://blog.csdn.net/taiyang1987912/article/details/50717179
Qt浅谈之四十五QSplitter实现自由伸缩滑动窗口的更多相关文章
- QSplitter实现自由伸缩滑动窗口部件(要在m_pSplitter中加入frame_4之前,给frame_4设置样式;之后设置无效)
实现代码如下: #include <QSplitter> QSplitter *m_pSplitter; m_pSplitter = new QSplitter(ui->frame_ ...
- Qt浅谈之四十九俄罗斯方块(代码来自网络)
一.简介 从网上下载了一个Qt实现的俄罗斯方块单机版的源码,觉得非常有意思,故以博客形式记录下来,以便慢慢来研究.在centos6.6下编译运行(注意程序运行需要读取pro目录的配置文件,若把编译目录 ...
- Qt浅谈之十八:GraphicsView框架事件处理(有源码下载)
一.简介 GraphicsView支持事件传播体系结构,可以使图元在场景scene中得到提高了已被的精确交互能力.图形视图框架中的事件都是首先由视图进行接收,然后传递给场景,再由场景给相应的图形项. ...
- Qt浅谈之三十九圆形进度条(已经有50篇了)
http://blog.csdn.net/taiyang1987912/article/category/2314763
- Qt浅谈内存泄露(总结)
Qt浅谈内存泄露(总结) 来源 http://blog.csdn.net/taiyang1987912/article/details/29271549 一.简介 Qt内存管理机制:Qt 在内部能够维 ...
- Qt浅谈之总结(整理)
Qt浅谈之总结(整理) 来源 http://blog.csdn.net/taiyang1987912/article/details/32713781 一.简介 QT的一些知识点总结,方便以后查阅. ...
- Qt::浅谈信号槽连接,参数在多线程中的使用
Qt的信号槽有五种连接方式定义在enum Qt::ConnectionType,下面简单介绍 Qt::AutoConnection:自动判断连接方式,如果信号发送对象和执行槽对象在同一线程,那么等于Q ...
- Qt浅谈之二十App自动重启及关闭子窗口
一.简介 最近因项目需求,Qt程序一旦检测到错误,要重新启动,自己是每次关闭主窗口的所有子窗口但有些模态框会出现问题,因此从网上总结了一些知识点,以备以后的应用. 二.详解 1.Qt结构 int ma ...
- Qt浅谈之二十App自动重启及关闭子窗口(六种方法)
一.简介 最近因项目需求,Qt程序一旦检测到错误,要重新启动,自己是每次关闭主窗口的所有子窗口但有些模态框会出现问题,因此从网上总结了一些知识点,以备以后的应用. 二.详解 1.Qt结构 int ma ...
随机推荐
- UML建模之状态图(Statechart Diagram)
状态图目录: 一.状态图简介(Brief introduction) 二.状态图元素(State Diagram Elements) 1.状态(States) 2.转移(Transitions) 3 ...
- cf509B Painting Pebbles
B. Painting Pebbles time limit per test 1 second memory limit per test 256 megabytes input standard ...
- POJ-1028(字符串模拟)
Web Navigation Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 31906 Accepted: 14242 ...
- libvirt-adabddad
kvm i686 libvirtError: internal error cannot load AppArmor profile 'libvirt-adabddad-35ba-b9ca-e250 ...
- JS~模拟表单在新窗口打开,避免广告拦截
说起广告拦截,这应该是浏览器的一个特性,它会将window.open产生的窗口默认为一个广告,将它进行拦截,但有时,这不是我们所希望的,有时,我们就是需要它在客户端的浏览器上弹出一个新窗口,以展示数据 ...
- android2.3 View视图框架源码分析之一:android是如何创建一个view的?
View是所有控件的一个基类,无论是布局(Layout),还是控件(Widget)都是继承自View类.只不过layout是一个特殊的view,它里面创建一个view的数组可以包含其他的view而已. ...
- JavaScript学习(2)
时间就像海绵里的水,要挤总还是有的,所以在最近不是太忙的时间里,我选择了挤时间,一点点的挤出了大把的时间,于是乎便迎来了我对javascript的第二阶段的学习,首先说下, 说起JavaScript大 ...
- javascript封装id|class|元素选择器
由于各个浏览器都支持的选择方法只有如下三种: 1 document.getElementById() 2 document.getElementsByName() 3 document.getElem ...
- USB 管道 && 端点
管道是对主机和usb设备间通信流的抽象. 管道和usb设备中的端点一一对应,一个usb设备含有多少个端点,其和主机进行通信时就可以使用多少条管道,且端点的类型决定了管道中数据的传输类型. ...
- Python:常见错误集锦(持续更新ing)
初学Python,很容易与各种错误不断的遭遇.通过集锦,可以快速的找到错误的原因和解决方法. 1.IndentationError:expected an indented block 说明此处需要缩 ...