• 10251阅读
  • 6回复

[提问]想从QDockWidget继承一个自定义的DockWidget,该怎么做呢? [复制链接]

上一主题 下一主题
离线johnyork
 

只看楼主 倒序阅读 楼主  发表于: 2015-02-27
各位高手大家好:
因为Qt默认的QDockWidget的特性不太能满足我的软件界面需求,我想从QDockWidget继承做一个自定义特色的DockWidget,但不知如何下手,请高手指教,谢谢:

QDockWidget默认的特性是:当Widget为浮动窗体时,双击标题栏将导致Widget Dock到主窗体中。

我需要的特性是:当Widget为浮动窗体是,双击标题栏导致Widget窗体最大化,而按标题栏的最小化按钮时则导致Widget Dock至主窗体。

我尝试过的办法:
1.为topLevelChanged信号定义槽函数,并在槽函数中检测Widget是否为浮动窗体,若是浮动窗体,则调用 setWindowFlags 函数并传递Qt::Window|Qt::WindowMinMaxButtonsHint参数给它,如此可在浮动窗体的标题栏上显示最大化、最小化按钮,但双击标题栏时的动作却变成了:先最大化,再Dock至主窗体;
2.参考qt-project.org论坛上的朋友给出的建议,重载函数mouseDoubleClickEvent,但是经过测试发现,在浮动窗体的标题栏双击并不能触发重载函数的执行,仅在窗体的控件界面上双击才能触发;查阅了QDockWidget的源代码,发现标题栏的双击动作是在QDockWidgetPrivate类中实现,而这个类Qt似乎并未在文档中向用户开放,因此貌似重载mouseDoubleClickEvent这条路也走不通。


因此,还有什么办法可以实现我的目的吗?
离线dbzhang800

只看该作者 1楼 发表于: 2015-02-27
注意一点

双击标题栏,对应 QEvent::NonClientAreaMouseButtonDblClick,而不是 QEvent::MouseButtonDblClick
离线johnyork

只看该作者 2楼 发表于: 2015-03-01
非常感谢您的回复。

我查了Qt的联机文档,QEvent::MouseButtonDblClick有继承类QMouseEvent可用,且在QWidget有对应的事件处理函数mouseDoubleClickEvent可以重载;二QEvent::NonClientAreaMouseButtonDblClick却没有对应的继承类定义和事件处理函数重载。因此:
1.我是否必须重载QWidget的event函数,并在重载函数中检查event的type是否为QEvent::NonClientAreaMouseButtonDblClick?
2.在重载的的event函数中是否必须重新调用QWidget::event函数以确保其他事件得以正确执行?
离线dbzhang800

只看该作者 3楼 发表于: 2015-03-01
1. 你这个情况,一般是重新实现 event() 【注意:这个叫 override(重写) 不叫 overload(重载)】
    但,你也可以用事件过滤器来实现。

2. 对
1条评分金钱+1
johnyork 金钱 +1 - 2015-03-05
离线johnyork

只看该作者 4楼 发表于: 2015-03-01
再次感谢!我确实将重写和重载给搞混淆了,今天又涨姿势了,谢谢。
您说的“事件过滤器”又怎么做呢?是否相对重写event函数来说要简单一点呢?
离线侠隐

只看该作者 5楼 发表于: 2015-03-02
回 johnyork 的帖子
johnyork:再次感谢!我确实将重写和重载给搞混淆了,今天又涨姿势了,谢谢。
您说的“事件过滤器”又怎么做呢?是否相对重写event函数来说要简单一点呢? (2015-03-01 23:12) 

事件过滤器如下:
重定义 bool  类::eventFilter(QObject* ,QEvent *) :根据Objeec是什么,相应的事件是什么来进行你需要的操作,也就是进行两个判定。
然后为你需要实现的部件intalEventlFilter();

个人觉得,使用事件过滤器是因为你需要实现在较多的部件重定义不同的事件,如果你只是需要重写较少的事件的话,比如你只需要实现你上面所提的事件,没必要使用。个人意见。。。
1条评分金钱+1
johnyork 金钱 +1 - 2015-03-05
离线johnyork

只看该作者 6楼 发表于: 2015-03-05
回 侠隐 的帖子
侠隐:事件过滤器如下:
重定义 bool  类::eventFilter(QObject* ,QEvent *) :根据Objeec是什么,相应的事件是什么来进行你需要的操作,也就是进行两个判定。
然后为你需要实现的部件intalEventlFilter();
....... (2015-03-02 23:49) 

非常感谢!
快速回复
限100 字节
 
上一个 下一个