2

我的一个QDockWidget. 我有几个有时可见有时不可见QWidget的项目。QDockwidget

我希望我的QDockWidget调整大小取决于它的内容......不仅QWidgets出现在其中,而且当它们消失时......

到目前为止,当我在其中显示QDockWidget更多内容时,我会调整自己的大小QWidgets,但是当我让它们消失时,会QDockWidget保持他以前的大小......

有什么想法可以帮助吗?

提前致谢!

4

2 回答 2

6

多年来,关于控制码头区域大小QDockWidget的帖子有很多。QMainWindow我也一直在努力解决这个问题,并且只能实现部分且有些不令人满意的解决方案。主要问题(如果你会原谅双关语)是无法从QMainWindow管理其停靠区域的工作的上下文中掌握停靠机制。尝试使用布局管理 - 尺寸策略和尺寸提示控件 - 无效;在QMainWindow更改停靠区大小时,它会做自己的事情。

首先,我取得了有限的成功:

QMainWindow子类 ( MW) 和QDockWidget子类 ( DW) 开始。有DW一个QWidget,有一个QHBoxLayout,即setWidgetDW。此布局有两个小部件 - 我将它们称为面板 - 其中一个面板旨在根据上下文显示或隐藏:当DW它位于底部或顶部停靠区域或浮动时显示,否则隐藏。使用sizeHint构造后的另一个面板的 (以及适当的边距间距)来设置 的“基本尺寸”,面板DW的构造sizeHint宽度将改变可见性,在适当时提供基本尺寸的增量:DW实现是提供了一个panel_visiblesizeHint用于通过将 setVisible 应用于面板并通过增量值更改值来启用或禁用变量面板的方法。DW及其面板的大小策略设置为最小。

MW和信号连接到一个DW dockLocationChanged插槽。这里,当,为假并报告或时,调用改变有效大小(当然,当不满足上述条件时调用)。调用, 和对停靠区大小没有影响。但是,如果调用停靠区域,则已正确调整大小(不需要或不需要)。当浮动(通过拖动或双击其标题栏)然后重新停靠(通过双击其标题栏或将其拖回侧停靠区域)时,这将按需要工作。到目前为止,一切都很好。topLevelChangedDW_resizeDW isVisibleisWindowMW::dockWidgetAreaLeftDockWidgetAreaRightDockWidgeAreaDW::panel_visible(false)DWDW::panel_visible(true)DW::resizeupdateGeometryupdateMWDW::setMaximumSize(DW::sizeHint())updateGeometryupdateDW

现在的问题:

强制将MW其停靠区域调整为规定DW大小后,DW需要从其固定大小约束中释放,以便用户可以通过将MW中间提供的吐出手柄拖动到停靠区域和中心区域来调整停靠区域的大小。显而易见的答案是调用DW::setMaximumSize(0xFFFFFF, 0xFFFFFF)“释放”DW约束。是的,除了在幕后进行的更新绘制优化将两个大小调整事件合并,结果导致初始停靠收缩动作丢失。通过在两个调用之间放置一个qApp->sendPostedEvents()and可以避免这种优化效果,停靠区域适合大小,然后释放,因此用户可以调整停靠区域的大小......有时。qApp->flush()setMaxmimumSizeDW

此解决方案在DW通过双击DW标题栏从浮动变为停靠时有效,但DWMW. 因此,例如,如果用户将DWdock 从左侧停靠到右侧停靠,则右侧停靠区域不会按预期调整大小;接收码头区域保持DW从一侧拖到另一侧期间产生的浮动的大小。如果DW在接收停靠区域中双击其标题栏(再次变为浮动),然后再次双击(将其返回到相同的停靠区域),则MW现在按预期适合停靠区域。仔细检查 - 通过监控MW::paintEvent- 我看到当码头区域最终达到预期大小时flush()紧随其后的是 a paintEvent,其中DW报告具有预期的大小,并且在第二个解除a 的setMaximumSize约束之后仍然出现预期的大小。但是,当被拖入停靠区时,紧随其后的是报告具有预期大小的位置,但是在这种情况下,第二个之后有两个s现在令人惊讶地具有其先前的浮动大小!DWpaintEventDWDWflush()paintEventDWsetMaximumSizepaintEventDW

DW在正确调整大小后,我还没有找到一种方法来防止这种无法解释的大小覆盖。MW似乎很清楚,在DW_resize槽处理返回之后,从MW发出导致槽的信号之前一直持有的大小信息,正在生成一个额外的调整大小事件。监控MW::eventFilter确实揭示了在DW_resize返回后发生的 Resize 事件,该事件将DW大小从插槽代码中设置的大小更改回浮动时的大小。当双击DW平铺栏用于将DW浮动移回侧停靠时,DW_resize插槽返回后不会发生额外的调整大小事件。

因此,挑战是如何防止在插槽DW中正确调整大小后发生意外的调整大小反转。DW_resize也许一些强制DW::resizeEvent可以避免这个问题....

当然,如果 Qt 开发人员能够在QMainWindowAPI 中为应用程序开发人员提供对其停靠管理活动的全面控制——尤其是停靠区域大小调整——和/或访问它用于停靠区域管理的小部件,那就更好了。

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

于 2011-05-13T05:54:05.813 回答
0

我一直有同样的问题。莫名其妙地放restoreState()两次已经为我解决了。
我正在使用 Qt 4.7.0。

void MainWnd::showEvent(QShowEvent *se){
QMainWindow::showEvent(se);

static bool first = true;

if (first){
   restoreState(...);
   restoreState(...);
   first = false;
}
}
于 2012-02-09T13:42:22.147 回答