如何强制剩余的小部件占用隐藏小部件留下的额外空间

How to force remaining widgets to take up extra space left by hidden widget?

本文关键字:小部 空间 隐藏 何强制      更新时间:2023-10-16

我正在开发一个Qt应用程序,该应用程序使用具有以下层次结构的多个小部件(如Qt Designer所示):

----- 1. QMainWindow
  |
  |----- 2. QWidget ("central widget")
  |  |
  |  |----- 3. CustomWidget
  |  |
  |  |----- 4. QScrollBar
  |
  |----- 5. QStatusBar
  |
  |----- 6. QToolBar ("top-left toolbar")
  |
  |----- 7. QToolBar ("top-right toolbar")

排列方式如下:

(1) ------------------------------
    | (6)         | (7)          |
    |----------------------------|
    | (3)                  | (4) |
    |                      |     |
    |                      |     |
    |                      |     |
    ------------------------------
    | (5)                        |
    ------------------------------

(注意,中心小部件被有意省略了,因为它看起来并不是一个明显不同的组件。)

设置文件指示QStatusBar是否应该显示调试信息。如果不应该,那么QStatusBar应该被隐藏。默认情况下,QStatusBar不隐藏;它只有在读取设置文件时才被隐藏。为此,我使用QWidget::hide()方法。

果然,QStatusBar是隐藏的。然而,剩下的小部件(特别是CustomWidget和QScrollBar)不会展开来填充(现在隐藏的)QStatusBar留下的空间。

我已经找到了QWidget::update()QWidget::repaint()方法,但它们在这里似乎没有多大用处。(我试过在QStatusBar小部件以及QMainWindow、中央小部件、QScrollBar和CustomWidget上使用它们,但都无济于事。)

我读了Qt页面上的大小政策似乎是有希望的。我使用以下大小策略设置:

  • QMainWindow: 'Preferred'(水平和垂直)
  • 中央小部件:'正在扩展'(水平和垂直)
  • QToolBars: 'Preferred'(水平),'Fixed'(垂直)
  • QStatusBar: 'Preferred'(水平和垂直)
  • CustomWidget: ' expanded '(水平和垂直)
  • QScrollBar: 'Fixed'(水平),' expand '(垂直)

这个想法是中央小部件应该填充两个qtoolbar和QStatusBar没有占用的空间。然后,CustomWidget应该填充(垂直)QScrollBar不使用的中央小部件中的所有空间。然而,这些大小策略似乎完全被忽视了——QStatusBar消失了,但其他小部件没有填满空间。

我怀疑答案可能在于Qt的布局管理,但在Qt设计器中玩了这个(看起来它适用于每个小部件的各种布局类),我找不到一个安排,使这个工作。

我需要做什么,使CustomWidget和QScrollBar利用剩余的空间时,QStatusBar隐藏?

编辑

在此期间,我通过调整QMainWindow的大小一个像素,然后再调整回来,实现了一个拼凑。resize事件似乎以我想要的方式流遍小部件。这是一个不优雅的解决方案,必须有一个方法来正确地做到这一点!

仔细阅读QMainWindowLayout(特别是sizeHint)的代码后,似乎这是在私有类中实现的正常行为。基本上,当状态栏被隐藏或显示时,不需要改变。

要改变这个,重写QMainWindow::sizeHint像这样:

QSize MyMainWindow::sizeHint() const
{
    QSize hint = QMainWindow::sizeHint();
    // if the status bar is invisible, add its height to the return value
    if (statusBar() && !statusBar()->isVisible())
        hint.rheight() += statusBar().sizeHint().height();
    return hint;
}

编辑
这是我能想到的最简单的解。如果它不工作,下一步将涉及重新实现resizeEvent并检查它是否是状态栏隐藏的结果。