Qt中,当QDockWidget的父窗口是一个不可以拖动的QTabWidget的时候实现拖动的方法
之前在做有关QDockWidget的内容时候遇到了瓶颈,那就是窗口弹出来之后拖动不了,也不可以放大和缩小,若是弹出来之后设置成了window的flags,也不可以拖动,而且也不是需要的效果。
1.弹出来之后的dockwidget的titlebar右边需要有3个按钮分别来控制放大与恢复、弹出来与收进去和关闭按钮。考虑到Qt自带的dockwidget弹出来后实现不了这个,所以参考了网上的方法,需要自己从QWidget中派生一个类来实现自己的titlebar
2.因为dockwidget是嵌套在QTabWidget中的,而tabwidget本身是不可以拖动的,所以此dockwiget也不可以拖动(Qt中子窗口的拖动是和父窗口有关联的),加上需要实现自己的dockwidget样式,所以也从QDockWidget中派生一个类
首先实现自己的titlebar:
class myDockWidgetTitleBar:public QWidget
{
Q_OBJECT private:
//自己需要的类成员定义
QSize sizeHint() const { return minimumSizeHint(); }
QSize mimimumSizeHint() const;//在写自己的titlebar时,这2个函数必须要实现 protected:
void paintEvent(QPaintEvent *event);
void mouseDoubleClickEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event); private slots:
//自己定义的一些槽函数,比如我这里需要实现放大缩小、浮动和关闭
void MaxMinDockWidget();
void FloatDockWidget();
void CloseDockWidget(); public:
myDockWidgetTitleBar(QWidget *parent = );
~myDockWigetTitleBar();
};
这里需要注意的是:若dockwidget没有titlebar则直接setTitleBarWidget(QWidget());这样可以只有一个dockwidget的窗口而没有窗口上面的titlebar。(方法来源于网上,源地址找寻不到了,若是找到再加上原有链接)
下面写一下在实现titlebar时必须要实现的函数的实现:
QSize *myDockWidgetTitleBar::minimumSizeHint() const
{
myDockWidget*dock_widget = qobject_cast<myDockWidget *>(parentWidget());
Q_ASSERT(dock_widget != );
QSize result(, );
if(dock_widget->features & QDockWidget::DockWidgetVerticalTitleBar)
{
result.transpose();
}
return result;
}
paintEvent主要用来在titlebar上绘制图标和位置。不过我这里因为这些按钮其他地方也要用到,所以我将按钮都定义成了类成员,同时在构造函数中给出了按钮的类型。其他的slots函数可以根据需求定义就行。
实现自己的dockwidget:
class myDockWidget:public QDockWidget
{
Q_OBJECT private:
//一些类成员变量
int _cur_point_pos;
int _margin_length;
QWidget *_default_title_bar;
myDockWidgetTitleBar *_dock_widget_title_bar; protected:
void mouseMoveEvent(QMouseEvent *event);//因为要实现拖动,所以这个鼠标移动事件必须要实现
void mousePressEvent(QMouseEvent *event);//拖动的时候鼠标左键应该是一直按压着的,所以需要在这个里面进行判断
void mouseReleaseEvent(QMouseEvent *event);
void closeEvent(QCloseEvent *event); public:
myDockWidget(QTabWidget *tab_widget, QWidget *parent = );
~myDockWidget();
};
需要注意的是这里的类定义中都用到了Q_OBJECT,若是在类中有信号和槽函数的定义,则必须要写此,具体的原因请参考Qt帮助手册。
“信号和槽函数的声明一般位于头文件中,同时在类声明的开始位置必须加上Q_OBJECT语句,这条语句是不可缺少的,它将告诉编译器在编译之前必须先应用 moc工具进行扩展。”--信号(Signal)与槽(Slot)-Qt中的典型机制
上面的类中还需要定义一个用来判断鼠标左键是否一直按压着的bool变量和鼠标之前点击的位置信息:
private:
bool _left_mose_press;
Qpoint _last_point_pos, _length_pos;
鼠标按压事件中:
void myDockWidget::mousePressEvent(QMouseEvent *event)
{
if(event->button == Qt::LeftButton)
{
_left_mouse_press = ture;
_last_point_pos = event->globalPos();
_cur_point_pos = CountFlag(event->pos(), CountColumn(event->pos()));
event->ignore();
}
}
鼠标释放事件中:
void myDockWidget::mouseReleaseEvent(QMouseEvent *event)
{
if(_left_mouse_press)
{
_left_mouse_press = false;
}
QApplication::restoreOverrideCursor();
event->ignore();
}
重点是这里的鼠标移动事件,这里处理的方法参考了【Qt编程】基于Qt的词典开发系列<四>--无边框窗口的缩放与拖动,并且这里里面有很详细的描述:有拖动窗口也有当鼠标放到四周显示不同形状进行放大缩小。这里将一个窗口划分成3*3的板块的方法还是不错的。
但是这里有一点不好的就是,每次拖动的时候都会重绘,若是窗口里面的内容比较复杂,当鼠标移动过快的时候便会出现窗口在某一个位置停下来了。这里还需要进一步的改进。
(移动窗口本身也有很多方法,但是考虑到要支持不同的平台,可能不能够只用到windows下的函数,所以选择了上面的方法,若只有windows平台,可以考虑下面的方法:
1. Qt窗口拖动及改变大小
3. 【Qt】移动无边框窗体
这些都是我当时查找到的一些方法,其实网上的方法大多也都是类似的,当然如果能够一个一个的看demo中的例子,就会发现其实Qt的源代码中也有类似的操作,网上的方法和Qt例子中的都大同小异)
当然Qt中也有获取当前屏幕大小的函数,这个可用来处理放大和缩小的时候看要到什么大小:
QRect desktop_rect = QApplication::desktop()->availableGeometry();
Qt中,当QDockWidget的父窗口是一个不可以拖动的QTabWidget的时候实现拖动的方法的更多相关文章
- QT中关闭应用程序和窗口的函数(quit(),exit()以及close()的区别)
使用QT编辑界面,其中带来很大方便的一点就是Qt中自带丰富的.种类齐全的类及其功能函数,程序员可以在编辑程序的过程中简单地直接调用.关于窗口关闭的操作,在这里指出常用的三个槽,即quit(),exit ...
- Qt入门(14)——父窗口部件和子窗口部件
这个例子演示了如何创建一个父窗口部件和子窗口部件.我们下面使用一个单一的父窗口部件和一个独立的子窗口部件编写界面. #include <qvbox.h>我们添加了一个头文件qvbox ...
- QT+创建两个不相干的窗口实现一个显示一个不显示
因为两个窗口互不相干,所以需要重新创建一个窗口类subWidget subWidget.cpp文件 #ifndef SUBWIDGET_H #define SUBWIDGET_H #include & ...
- HTML中IFrame父窗口与子窗口相互操作
一.Iframe篇 //&&&&&&&&&&&&&&&&&&am ...
- QT中QWidget类简介
一.详细描述 QWidget类是所有用户界面对象的基类.通俗的来讲,Qt基本上所有的UI类都是由QWidget继承出来的,而QWidget继承于QObject, 大家可以查阅Qt source 即可 ...
- Qt中的内存回收机制
Qt中的内存回收机制 在Qt中创建对象的时候会提供一个 Parent对象指针(可以查看类的构造函数),下面来解释这个parent到底是干什么的. QObject是以对象树的形式组织起来的.当你创建一个 ...
- JavaScript(Iframe、window.open、window.showModalDialog)父窗口与子窗口之间的操作
一.Iframe 篇 公共部分 //父对象得到子窗口的值 //ObjectID是窗口标识,ContentID是元素ID function GetValue(ObjectID,ContentID) { ...
- 总结JavaScript(Iframe、window.open、window.showModalDialog)父窗口与子窗口之间的操作
一.Iframe 篇 //&&&&&&&&&&&&&&&&&&a ...
- Qt入门(9)——Qt中的线程支持
Qt对线程提供了支持,基本形式有独立于平台的线程类.线程安全方式的事件传递和一个全局Qt库互斥量允许你可以从不同的线程调用Qt方法.警告:所有的GUI类(比如,QWidget和它的子类),操作系统核心 ...
随机推荐
- FZU 2213 Common Tangents 第六届福建省赛
题目链接:http://acm.fzu.edu.cn/problem.php?pid=2213 题目大意:两个圆,并且知道两个圆的圆心和半径,求这两个圆共同的切线有多少条,若有无数条,输出-1,其他条 ...
- TabHost自定义外观
博客园:http://www.cnblogs.com 农民伯伯: http://www.cnblogs.com/over140 版本 新浪微博 weibo_10235010.apk 正文 一.效果图 ...
- Centos6.4 xen编译部署
ruiy亲测成功,现将步骤总结如下,一步步往下将可 原文链接 http://blog.csdn.net/liyakun1992421/article/details/9071061 xen 与 kvm ...
- Nginx具体的压缩配置
以下是自学it网--中级班上课笔记 网址:www.zixue.it 常用以下配置 gzip on|off gzip_buffers 4K|8K 缓冲(和硬盘块相当) gzip_comp_level [ ...
- javascript中String 对象slice 和substring 区别
1.slice(start,stop)和substring(start,stop) 方法都是用于提取字符串中从start开始到stop-1间的字符(因为字符串索引是从0开始).其中 start必 ...
- UNITY打包问题
1,打包有二种,打包可执行程序-player,打包资源包-assetbundle 2,打包player后,在PC平台去看打包后对应的资源大小,发现比原始资源小得多,模型资源压缩率约60%,图资源压缩率 ...
- TCP/UDP是如何传输的?
一.网络模型: OSI参考模型 TCP/IP参考模型 二.网络通讯要素 IP地址: 网络中设备的标识 不易记忆,可用主机名 本机回环地址:127.0.0.1 主机名: localhost 端口号: 用 ...
- Datediff函数 助你实现不同进制时间之间的运算
在VB开发环境中实现时间之间的加减运算有很多种方法,前不久自己无意中发现了Datediff函数,它能够比较简单.全面地实现我们比较常用的时间之间的运算,今由自己的研究,搞清了它的一些用法,拿来和大家分 ...
- TR069协议向导——一个帮助你了解TR069协议的简明教程(一)
您也能够到下面地址下载: http://download.csdn.net/source/993034 1.为什么须要TR069 随着VoIP.IPTV等越来越多IP终端设备的普及(尤其在家庭中 ...
- abap中的弹出窗体函数
POPUP_TO_CONFIRM_WITH_MESSAGE 会话框确实处理步骤; 用识别正文POPUP_TO_SELECT_MONTH 日历:弹出 POPUP_TO_C ...