QMdiArea:第一个选项卡工作正常,第二个选项卡的内容太小
Posted
技术标签:
【中文标题】QMdiArea:第一个选项卡工作正常,第二个选项卡的内容太小【英文标题】:QMdiArea: First tab works fine, second tab's content is way too small 【发布时间】:2014-09-23 15:57:00 【问题描述】:情况:作为我的应用程序的中心小部件,我有一个处于选项卡模式的 QMdiArea(包装在继承自 QMdiArea 的自定义类中)。当我现在通过addSubWindow()
添加第一个QMdiSubWindow 时,一切都很好,这意味着窗口及其内容被最大化以占用QMdiArea 的所有空间。但是,一旦我添加了第二个子窗口,就会出现以下问题:
问题:第二个窗口的内容没有显示,而是第一个窗口的内容继续显示(尽管第二个选项卡在视觉上具有焦点),但尺寸减小了.它只占用几个像素。但是,如果我现在切换回第一个子窗口/选项卡(通过单击缩小尺寸的小部件,然后自动返回到最大尺寸或通过选择第一个选项卡标题),然后再次选择第二个,一切都很好 =第二个选项卡的小部件/编辑器现在显示并最大化。
但只有在我关闭第二个选项卡之前,才会显示第一个选项卡中的内容(如预期的那样),但同样只能以小尺寸显示!
截图:
另一个相关的测试用例:创建第一个选项卡并按预期显示全尺寸。如果我现在简单地调整整个 QMainWindow 的大小,我的选项卡中的小部件周围会突然出现一个模糊的边框。因此,它似乎处于最大化模式和带边框的正常模式之间的混合状态。这会产生任何新的潜在客户吗?
截图:
到目前为止,我没有使用任何明确定义的布局,但鉴于第一个选项卡工作正常,并且在手动来回切换所有其他选项卡之后,我认为它应该可以不使用。
我需要设置明确的布局对象吗?为什么它适用于第一个标签,而不适用于第二个?
一些代码作为基础:这是在我的自定义 QMdiArea 类中执行的逻辑,负责添加新的子类:
// Note: pEditor inherits from / is a QMdiSubWindow itself
if(!pEditor->isInitialized())
pEditor->initialize();
pEditor->setWidget(pEditor->getEditorWidget());
pEditor->setInitialized(true);
pEditor->beforeDisplay();
addSubWindow(pEditor);
pEditor->showMaximized();
// HACK START
pExisting = subWindowList().at(0);
if(pExisting)
setActiveSubWindow(pExisting);
// HACK END
更新:添加了 hack proposed by N1ghtLight。在编码中这样标记。
更新 2: 编辑/更正问题描述 + 带有屏幕截图的新测试用例。
【问题讨论】:
您是否尝试为刚刚创建的 QMdiSubWindow 的新 pEditor 实例调用 void QMdiArea::setActiveSubWindow(QMdiSubWindow * window)?例如,在 addSubWindow(pEditor) 之后调用它。另外我想知道是否需要调用 showMaximized。 @N1ghtLight:这不会改变任何事情。新选项卡已经处于活动状态(请参阅我新添加的屏幕截图)。关于showMaximized()
:如果我忽略它,子窗口内的小部件根本不会显示,因为它永远不会设置为可见。
目前,丑陋的解决方法实际上可能是两次调用 setActiveSubWindow - 对于一些可用的 sub mdi,然后是新创建的 sub。这应该模拟您单击第一个然后返回第二个时的情况。我也有一种感觉,以前我使用 mdi(3 年前)时遇到了同样的问题,只是停止了这种丑陋的解决方法:)
@N1ghtLight 这确实有效。谢谢你的提示!然而,我希望我们能够找到一个“合适的”解决方案。但请随时添加您的想法作为答案。如果没有更好的弹出,它可能会得到赏金。
这里是我的带有 mdi 子窗口创建的测试项目的链接...mega.co.nz/… ...不幸的是,它对我来说很好...这让我认为它的大小有问题项目中的 mdiSubWindow 内容
【参考方案1】:
在将 N1ightLight 中的示例项目与我自己的实现进行了数小时的比较之后,我终于发现了核心差异。实际上有两个问题在起作用:
由于某种原因,我在创建 MDI 子窗口时有以下行,这显然搞砸了大小处理。摆脱这条线消除了对先前提出的黑客的任何需要。结合 N1ghtLight 提出的布局,现在可以优雅地处理所有大小更改。
setWindowState(Qt::WindowMaximized); // do not use that state!
关于标签关闭的第二部分(关闭一个标签并没有以预期的方式和大小调出下一个标签),实际上在 Qt 文档中进行了解释:
当你创建你自己的子窗口时,你必须设置 Qt::WA_DeleteOnClose 小部件属性,如果你希望窗口在 MDI 区域中关闭时被删除。否则,窗口将被隐藏,MDI 区域不会激活下一个子窗口。
自从我创建自己的子窗口以来,我必须设置该标志,但我从未这样做过,因为我还想阻止 Qt 自动删除我的内容小部件。我现在的解决方案是设置标志,但是每当 MDI 子项即将关闭时,我都会删除小部件的链接,因此 Qt 无法删除它。
void CustomMDIWindow::closeEvent(QCloseEvent* pEvent)
setWidget(0);
pEvent->accept();
我会将自己的答案标记为正确答案,但会将赏金奖励给 N1ightLight,因为他的支持最终让我找到了最终解决方案。
【讨论】:
【参考方案2】:丑陋的解决方法实际上可以是两次调用setActiveSubWindow()
:首先是一些可用的子窗口,然后是新创建的子窗口。这应该模拟您单击第一个选项卡然后返回到第二个选项卡时的情况。
【讨论】:
正如我现在编辑/更正的问题描述中所解释的,这仅解决了选项卡创建阶段。当我关闭现有选项卡时,我遇到了相同/类似的问题。鉴于此时只剩下一个选项卡,因此没有第二个选项卡可以通过setActiveSubWindow()
临时切换。以上是关于QMdiArea:第一个选项卡工作正常,第二个选项卡的内容太小的主要内容,如果未能解决你的问题,请参考以下文章
swift - 如何从第一个选项卡到达第二个选项卡导航堆栈?