打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Qt中,当QDockWidget的父窗口是一个不可以拖动的QTabWidget的时候实现拖动的方法

    之前在做有关QDockWidget的内容时候遇到了瓶颈,那就是窗口弹出来之后拖动不了,也不可以放大和缩小,若是弹出来之后设置成了window的flags,也不可以拖动,而且也不是需要的效果。

    1.弹出来之后的dockwidget的titlebar右边需要有3个按钮分别来控制放大与恢复、弹出来与收进去和关闭按钮。考虑到Qt自带的dockwidget弹出来后实现不了这个,所以参考了网上的方法,需要自己从QWidget中派生一个类来实现自己的titlebar

    2.因为dockwidget是嵌套在QTabWidget中的,而tabwidget本身是不可以拖动的,所以此dockwiget也不可以拖动(Qt中子窗口的拖动是和父窗口有关联的),加上需要实现自己的dockwidget样式,所以也从QDockWidget中派生一个类

    首先实现自己的titlebar:

 1 class myDockWidgetTitleBar:public QWidget 2 { 3     Q_OBJECT 4  5 private: 6     //自己需要的类成员定义 7     QSize sizeHint() const { return minimumSizeHint(); } 8     QSize mimimumSizeHint() const;//在写自己的titlebar时,这2个函数必须要实现 9 10 protected:11     void paintEvent(QPaintEvent *event);12     void mouseDoubleClickEvent(QMouseEvent *event);13     void mouseReleaseEvent(QMouseEvent *event);14 15 private slots:16     //自己定义的一些槽函数,比如我这里需要实现放大缩小、浮动和关闭17     void MaxMinDockWidget();18     void FloatDockWidget();19     void CloseDockWidget();20 21 public:22     myDockWidgetTitleBar(QWidget *parent = 0);23     ~myDockWigetTitleBar();24 };

    这里需要注意的是:若dockwidget没有titlebar则直接setTitleBarWidget(QWidget());这样可以只有一个dockwidget的窗口而没有窗口上面的titlebar。(方法来源于网上,源地址找寻不到了,若是找到再加上原有链接)

    下面写一下在实现titlebar时必须要实现的函数的实现:

 1 QSize *myDockWidgetTitleBar::minimumSizeHint() const 2 { 3     myDockWidget*dock_widget = qobject_cast<myDockWidget *>(parentWidget()); 4     Q_ASSERT(dock_widget != 0); 5     QSize result(50, 30); 6     if(dock_widget->features & QDockWidget::DockWidgetVerticalTitleBar) 7     { 8         result.transpose(); 9     }10     return result;11 }

    paintEvent主要用来在titlebar上绘制图标和位置。不过我这里因为这些按钮其他地方也要用到,所以我将按钮都定义成了类成员,同时在构造函数中给出了按钮的类型。其他的slots函数可以根据需求定义就行。

    实现自己的dockwidget:

 1 class myDockWidget:public QDockWidget 2 { 3     Q_OBJECT 4  5 private: 6     //一些类成员变量 7     int _cur_point_pos; 8     int _margin_length; 9     QWidget *_default_title_bar;10     myDockWidgetTitleBar *_dock_widget_title_bar;11 12 protected:13     void mouseMoveEvent(QMouseEvent *event);//因为要实现拖动,所以这个鼠标移动事件必须要实现14     void mousePressEvent(QMouseEvent *event);//拖动的时候鼠标左键应该是一直按压着的,所以需要在这个里面进行判断15     void mouseReleaseEvent(QMouseEvent *event);16     void closeEvent(QCloseEvent *event);17 18 public:19     myDockWidget(QTabWidget *tab_widget, QWidget *parent = 0);20     ~myDockWidget();21 };

    需要注意的是这里的类定义中都用到了Q_OBJECT,若是在类中有信号和槽函数的定义,则必须要写此,具体的原因请参考Qt帮助手册。

   上面的类中还需要定义一个用来判断鼠标左键是否一直按压着的bool变量和鼠标之前点击的位置信息:

1 private:2     bool _left_mose_press;3     Qpoint _last_point_pos, _length_pos;

    鼠标按压事件中:

 1 void myDockWidget::mousePressEvent(QMouseEvent *event) 2 { 3     if(event->button == Qt::LeftButton) 4     { 5         _left_mouse_press = ture; 6         _last_point_pos = event->globalPos(); 7         _cur_point_pos = CountFlag(event->pos(), CountColumn(event->pos())); 8         event->ignore(); 9     }          10 }

    鼠标释放事件中:

1 void myDockWidget::mouseReleaseEvent(QMouseEvent *event)2 {3     if(_left_mouse_press)4     {5          _left_mouse_press = false;6     }7     QApplication::restoreOverrideCursor();8     event->ignore();   9 }

    重点是这里的鼠标移动事件,这里处理的方法参考了【Qt编程】基于Qt的词典开发系列<四>--无边框窗口的缩放与拖动,并且这里里面有很详细的描述:有拖动窗口也有当鼠标放到四周显示不同形状进行放大缩小。这里将一个窗口划分成3*3的板块的方法还是不错的。

    但是这里有一点不好的就是,每次拖动的时候都会重绘,若是窗口里面的内容比较复杂,当鼠标移动过快的时候便会出现窗口在某一个位置停下来了。这里还需要进一步的改进。

    (移动窗口本身也有很多方法,但是考虑到要支持不同的平台,可能不能够只用到windows下的函数,所以选择了上面的方法,若只有windows平台,可以考虑下面的方法:

    1. Qt窗口拖动及改变大小

    2. Qt 无标题无边框程序的拖动和改变大小

    3. 【Qt】移动无边框窗体

    这些都是我当时查找到的一些方法,其实网上的方法大多也都是类似的,当然如果能够一个一个的看demo中的例子,就会发现其实Qt的源代码中也有类似的操作,网上的方法和Qt例子中的都大同小异)

     当然Qt中也有获取当前屏幕大小的函数,这个可用来处理放大和缩小的时候看要到什么大小:

1 QRect desktop_rect = QApplication::desktop()->availableGeometry();

 

 

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
自定义 Qt 窗口标题栏
QT程序初始化时QDockWidget大小的调整方法
QT之QDockWidget使用详解
c – 如何使Qt子小部件高度相等?
Qt 样式表之QSS
qt QTabWidget设置tab头的宽度
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服