QDockWidget更改其内容时的行为 [英] QDockWidget behavior when changing its content
问题描述
我的一个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
,其中一个QHBoxLayout
在DW
中为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
dockLocationChanged
和topLevelChanged
信号连接到DW_resize
插槽.此处,当DW
isVisible
,isWindow
为假并且MW::dockWidgetArea
报告LeftDockWidgetArea
或RightDockWidgeArea
时,调用DW::panel_visible(false)
来更改有效的DW
大小(不满足上述条件时)当然会遇到DW::panel_visible(true)
).调用MW
中的DW::resize
,updateGeometry
和update
对扩展坞区域大小没有影响.但是,如果调用DW::setMaximumSize(DW::sizeHint())
,则正确调整了停靠区域的大小(不需要updateGeometry
或update
).当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
之后,在此情况下有两个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 paintEvent
s 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屋!