QDockWidget更改其内容时的行为 [英] QDockWidget behavior when changing its content

查看:120
本文介绍了QDockWidget更改其内容时的行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的一个QDockWidget遇到问题.我在QDockwidget中有几个QWidget项,有时看不见,有时不可见.

I'm facing a problem with one of my QDockWidget. I have several QWidget items in a QDockwidget that are sometimes visible sometimes not.

我希望我的QDockWidget根据其内容调整自身大小……不仅在QWidgets出现时,而且在它们消失时……

I would like that my QDockWidget resizes itself depending on its content... Not only when QWidgets appear in it, but also when they disappear...

到目前为止,当显示更多QWidgets时,我的QDockWidget会自动调整大小,但是当我将其消失时,QDockWidget会保持其先前的大小...

So far, my QDockWidget resizes itself when more QWidgets are displayed in it, but when I make them disappear, the QDockWidget stays at his previous size...

有什么想法需要帮助吗?

Any ideas to help ?

提前谢谢!

推荐答案

多年来,有很多关于控制QMainWindow停靠区中QDockWidget大小的文章.我也一直在努力解决这个问题,只能够实现部分解决方案,但有些不能令人满意.主要问题(如果您会打扰的话)是无法从QMainWindow的上下文中掌握对接机制,而该c9用于管理其对接区域.尝试使用布局管理-大小策略和大小提示控件-无效; QMainWindow在更改停靠区大小时会做自己的事情.

There have been various posts over the years regarding control of the size of a QDockWidget in a QMainWindow dock area. I, too, have been struggling with this issue and have only been able to achieve a partial, and somewhat unsatisfactory, solution. The main problem (if you'll excuse the pun) is the inability to get a grip on the docking mechanism from the context of the QMainWindow that does the work of managing its dock areas. Attempts to use layout management - size policy and size hint controls - are not effective; the QMainWindow does its own thing when changing dock area sizes.

首先,我取得的成就有限:

First, what limited success I have had:

QMainWindow子类(MW)和QDockWidget子类(DW)开始. DW具有一个QWidget,其中一个QHBoxLayoutDW中为setWidget.此布局有两个小部件-我称它们为面板-其中一个面板打算根据上下文显示或隐藏:DW在底部或顶部停靠区或悬空时显示,否则隐藏.使用构造后的另一个面板的sizeHint(以及适当的页边距)来设置DW的基本尺寸",所构造的面板的sizeHint宽度将改变能见度,从而增加适当时的基本大小:DW实现提供了panel_visible方法,该方法用于通过将setVisible应用于面板并通过递增值更改sizeHint的值来启用或禁用可变面板. DW及其面板的大小策略设置为最小".

Starting with a QMainWindow subclass (MW) and a QDockWidget subclass (DW). The DW has a QWidget, with a QHBoxLayout, that is setWidget in the DW. This layout has two widgets - I'll call them panels - with one of these panels intended to be shown or hidden depending on context: shown when the DW is in the bottom or top dock areas or floating, hidden otherwise. The sizeHint of the other panel after construction is used (along with appropriate margin spacing) to set the "base size" of the DW, with the constructed sizeHint width of the panel that will change visibility providing the increment to the base size when appropriate: the DW implementation is provided with a panel_visible method that is used to enable or disable the variable panel by applying setVisible to the panel and changing the value of the sizeHint by the increment value. The size policy of the DW and its panels are set to Minimum.

MW中,DW dockLocationChangedtopLevelChanged信号连接到DW_resize插槽.此处,当DW isVisibleisWindow为假并且MW::dockWidgetArea报告LeftDockWidgetAreaRightDockWidgeArea时,调用DW::panel_visible(false)来更改有效的DW大小(不满足上述条件时)当然会遇到DW::panel_visible(true)).调用MW中的DW::resizeupdateGeometryupdate对扩展坞区域大小没有影响.但是,如果调用DW::setMaximumSize(DW::sizeHint()),则正确调整了停靠区域的大小(不需要updateGeometryupdate).当DW浮动(通过拖动或双击其标题栏)然后重新固定(通过双击其标题栏或将其拖动回侧面停靠区域)时,此方法可以按预期工作.到目前为止,一切都很好.

In the MW the DW dockLocationChanged and topLevelChanged signals are connected to a DW_resize slot. Here, when the DW isVisible, isWindow is false and MW::dockWidgetArea reports either LeftDockWidgetArea or RightDockWidgeArea, DW::panel_visible(false) is called to change the effective DW size (when the above conditions are not met DW::panel_visible(true) is called, of course). Invoking DW::resize, and updateGeometry and update in the MW has no effect on the dock area size. However if DW::setMaximumSize(DW::sizeHint()) is called the dock area is correctly resized (no updateGeometry or update needed). This works as desired when the DW is floated (by dragging or double-clicking its title bar) and then redocked (by double-clicking its title bar or dragging it back over a side dock area). So far, so good.

现在要抓住了:

已强制MW将其停靠区调整为指定的DW尺寸,DW需要从其固定大小限制中释放,以便用户可以通过拖动由以下按钮提供的吐水手柄来调整停靠区的大小. MW到码头区域和中央区域之间.显而易见的答案是只调用DW::setMaximumSize(0xFFFFFF, 0xFFFFFF)来释放" DW约束.是的,除了在幕后进行的更新绘画优化将两个大小调整事件合并在一起之外,结果是失去了最初的停靠收缩动作.通过在两个setMaxmimumSize调用之间放置qApp->sendPostedEvents()qApp->flush(),可以避免这种优化效果,将停靠区域调整为DW大小,然后放开,以便用户可以调整停靠区域的大小.有时.

Having coerced the MW to fit its dock area to the prescribed DW size the DW needs to be released from its fixed size constraint so the user can resize the dock area by dragging the spit handle provided by the MW between to the dock area and the central area. The obvious answer is to just call DW::setMaximumSize(0xFFFFFF, 0xFFFFFF) to "release" the DW constraints. Yes, except that update painting optimization that goes on behind the scenes coalesces the two sizing events with the result that the initial dock shrink action is lost. By putting a qApp->sendPostedEvents() and qApp->flush() between the two setMaxmimumSize calls this optimizing effect is avoided, the dock area is fit to the DW size and then left released so the dock area can be resized by the user ... sometimes.

当通过双击DW标题栏使DW从浮动变为停靠时,此解决方案有效,但当DW拖动到MW的侧停靠栏中时,此解决方案无效.因此,例如,如果用户将DW从左停靠区拖到右停靠区,则不会按预期调整右停靠区的大小;接收码头区域保持从一侧拖动到另一侧的过程中产生的浮动DW的大小.如果在接收停靠区中的DW双击其标题栏(再次变为浮动),然后再次双击(以使其返回相同的停靠区),则MW现在将适合预期的停靠区.在仔细检查时-通过监视MW::paintEvent-我看到,当停靠区域达到预期大小时,flush()之后紧接着是paintEvent,其中DW报告具有预期大小,并且第二个<解除DW约束的c73>,而DW仍是预期大小,则会出现paintEvent.但是,当DW被拖到停靠区时,flush()紧接着是paintEvent,其中DW报告具有预期的大小,但是在第二个setMaximumSize之后,在此情况下有两个 s,而DW现在具有以前的浮动大小!

This solution works when the DW goes from floating to docked by double-clicking the DW title bar, but not when the DW is dragged to a side dock in the MW. So, for example, if the user drags the DW from the left dock to the right dock the right dock area is not resized as expected; the receiving dock area remains the size of the floating DW that is produced during the drag from one side to another. If the DW in the receiving dock area has its title bar double-clicked (to become floating again) and then double-clicked again (to return it to the same dock area) the MW now fits the dock area as intended. On close inspection - by monitoring the MW::paintEvent - I see that when the dock area ends up the intended size the flush() is immediately followed by a paintEvent where the DW reports having the intended size and after the second setMaximumSize that unconstrains the DW a paintEvent occurs with the DW still the intended sized. But when the DW is dragged into the dock area the flush() is again immediately followed by paintEvent where the DW reports having the intended size, but after the second setMaximumSize in this case there are two paintEvents with the DW now surprisingly having its previous floating size!

我还没有找到一种方法来防止在正确设置DW大小后出现这种无法解释的覆盖.似乎很明显,在DW_resize时隙处理返回之后,MW正在根据MW一直保持的大小信息从发出指向该时隙的信号之前保持的大小信息中生成另一个调整大小事件.监视MW::eventFilter确实确实显示了DW_resize返回后发生的Resize事件,该事件将DW的大小从插槽代码中设置的大小更改为浮动时的大小.双击DW磁贴条用于将DW从浮动移回侧面停靠栏后,在DW_resize插槽返回后不会发生其他调整大小事件.

I have yet to find a way to prevent this unexplained overriding of the DW size after it has been correctly sized. It seems clear that an additional resize event is being generated by the MW after the DW_resize slot processing has returned, from size information that the MW has been holding from before the signals were emitted that lead to the slot. Monitoring the MW::eventFilter does indeed reveal a Resize event occurring after DW_resize has returned that changes the DW size from what it had been set to in the slot code back to its size when it was floating. When double-clicking the DW tile bar is used to move the DW from floating back into the side dock no additional Resize event occurs after the DW_resize slot returns.

接下来的挑战是,如何防止在DW_resize插槽中正确设置了DW的大小之后发生意外的重新调整大小的情况.也许DW::resizeEvent中的某些强制措施可以避免此问题....

The challenge, then, is how to prevent the unexpected resize reversion from happening after the DW has been correctly sized in the DW_resize slot. Perhaps some coercion in DW::resizeEvent will avoid this problem ....

当然,更好的情况是,Qt开发人员是否将在QMainWindow API中为应用程序开发人员提供全面的控制,以控制其接驳管理活动-尤其是接驳区域的大小-和/或访问其用于接驳的窗口小部件区域管理.

Better, of course, would be if the Qt developers would provide the application developer thorough controls in the QMainWindow API over its dock management activities - especially dock area sizing - and/or access to the widgets that it uses for dock area management.

我目前在Linux,OS X和MS/Windows上使用Qt 4.6.2.上面的调试报告是在Intel OS X 10.6.7系统上完成的.不同平台上的结果有所不同,但是基本问题是相同的.也许这些QMainWindow/QDockWidget问题已经在更高版本的Qt中得到了解决?也许有人对这里发生的事情有更深入的了解,可以提供一个简单的解决方案?

I am currently using Qt 4.6.2 on Linux, OS X and MS/Windows. The debug reports, above, were done on an Intel OS X 10.6.7 system; results differ somewhat on the different platforms, but the basic problem is the same. Perhaps these QMainWindow/QDockWidget issues have been dealt with in a later version of Qt? Perhaps someone has deeper insight into what is going on here and can offer a simple solution?

这篇关于QDockWidget更改其内容时的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆