布局内容更改后将 QMainWindow 调整为最小尺寸

Resize QMainWindow to minimal size after content of layout changes

我正在使用 QMainWindow 的子类,我在其中声明了一个中央小部件。此小部件包含一个 QGridLayout,其中包含一组按钮。按钮的数量可以增加或减少,具体取决于用户的输入。间距设置为零,以便所有按钮聚集在一起。默认情况下,它看起来像这样:

如果增加按钮的数量,网格和window也会增长得很好;但是,如果减少按钮的数量,它将如下所示:

现在我想调整 window/layout/widget 的大小,以便所有按钮都可以使用最小的 space。我尝试了各种各样的事情,但都无济于事。我查看了 this and this 问题,以及 Qt 板上的各种线程,但其中 none 对我有用。

我的布局构建如下:

self.grid = QtGui.QGridLayout()
self.grid.setSpacing(0)

hBox = QtGui.QHBoxLayout()
hBox.addWidget(...)

vBox = QtGui.QVBoxLayout(self.widget)
vBox.addLayout(hBox)
vBox.addLayout(self.grid)

self.setCentralWidget(self.widget)

我尝试用...调整大小

self.widget.layout().activate()
self.resize(self.minimumSize())
# self.resize(self.sizeHint())

...以及其他各种方法。我还尝试设置 window 和网格的大小策略。

您可以在更改小部件数量后将 window 的大小调整为 minimumSizeHint() :

self.resize(minimumSizeHint())

这会将 window 缩小到最小尺寸。但是您应该考虑到在事件循环中处理某些事件之前不会计算最小大小。所以当按钮的数量改变时,只需处理事件循环一些迭代,然后调整到最小。

就像:

for i in range(0, 10):
      QApplication.processEvents()

self.resize(minimumSizeHint())

另一种选择是单发一个 QTimer,它调用一个插槽,您可以在其中将 window 的大小调整到最小。这样,当您调整 window 大小时,最小尺寸提示会被正确计算。

虽然已经有人回答了,但我找到了一个非常简单、优雅的解决方案here。很难找到,因为问题是针对 Qt 而不是 PySide 中的这个问题。您必须将它翻译成 PySide,但这真的很简单。

本质上,您想要设置要自动调整大小的布局的大小约束 QtGui.QLayout.SetFixedSize,如下所示:

vBox = QtGui.QVBoxLayout(self.widget)
vBox.setSizeConstraint(QtGui.QLayout.SetFixedSize)

该代码一点也不直观,但它有效。

对于像我一样不能立即了解如何使用 QTimer 的人:

def function_with_blown_window_size(self)
    ...
    # 1 ms was too low for a refresh -> singleShot timer with 10ms delay
    QTimer.singleShot(10, self.window_size_readjust)

def window_size_readjust(self):
    self.adjustSize()                     # worked in my case
    #self.resize(self.minimumSizeHint())  # alternative worked equally well