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:第一个选项卡工作正常,第二个选项卡的内容太小的主要内容,如果未能解决你的问题,请参考以下文章

jQuery 地址子选项卡(嵌套选项卡)(深度链接)

引导选项卡中的数据表大小不正确

swift - 如何从第一个选项卡到达第二个选项卡导航堆栈?

UIB 选项卡 - 设置第二个选项卡处于活动状态

如何从另一个选项卡上的场景切换或弹出选项卡式应用程序中第一个选项卡的第二个场景?

引导选项卡单击后不显示内容