调整 QSplitter 的大小不遵守 QSizePolicy 或 setStretchFactor?

Resizing QSplitter doesn't respect QSizePolicy or setStretchFactor?

我在 QSplitter 中设置了项目的大小策略,但它似乎没有任何影响。当我在下面的示例中调整 window 大小时,我希望我的左侧小部件在达到其大小提示 (QSizePolicy.Preferred) 后停止增长,而右侧小部件尽可能大地扩展 (QSizePolicy.Expanding ).


如果我将它们放在布局中,它会起作用:

from PyQt5 import QtWidgets, QtCore

app = QtWidgets.QApplication([])


class ColoredBox(QtWidgets.QFrame):
    def __init__(self, color):
        super().__init__()
        self.setStyleSheet(f'background-color: {color}')

    def sizeHint(self) -> QtCore.QSize:
        return QtCore.QSize(200, 200)


box1 = ColoredBox('red')
box2 = ColoredBox('green')

splitter = QtWidgets.QHBoxLayout()
splitter.setContentsMargins(0, 0, 0, 0)
splitter.setSpacing(0)

splitter.addWidget(box1)
splitter.addWidget(box2)

box1.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
box2.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)

container = QtWidgets.QWidget()
container.setLayout(splitter)
container.show()

app.exec_()

但是如果我把它们放在 QSplitter 中它就不起作用了,分离器只是在它们之间均匀地分裂 space:

from PyQt5 import QtWidgets, QtCore
from PyQt5.QtCore import Qt

app = QtWidgets.QApplication([])


class ColoredBox(QtWidgets.QFrame):
    def __init__(self, color):
        super().__init__()
        self.setStyleSheet(f'background-color: {color}')

    def sizeHint(self) -> QtCore.QSize:
        return QtCore.QSize(200, 200)


box1 = ColoredBox('red')
box2 = ColoredBox('green')

splitter = QtWidgets.QSplitter(Qt.Horizontal)
splitter.setStretchFactor(0, 0)
splitter.setStretchFactor(1, 1)

splitter.addWidget(box1)
splitter.addWidget(box2)

box1.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
box2.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)

container = QtWidgets.QMainWindow()
container.setCentralWidget(splitter)
container.show()

app.exec_()

布局与拆分器:

问题出在您设置拉伸因子的时间过早。

    如果在尚不存在的小部件索引上完成
  • setStretchFactor() 将被忽略(请参阅 source code 了解其实现);
  • QSplitter 根据大小策略调整小部件的比例;大小策略还包括 horizontal and vertical 拉伸因子,每当使用基本 setSizePolicy(horizontalPolicy, verticalPolicy) 再次设置时,它们都会重置为 0 默认值(这意味着您可以在 QSizePolicy 中指定拉伸,即与使用 setStretchFactor).
  • 相同

解决方案很简单:在添加小部件设置它们的策​​略之后移动setStretchFactor

显然,一种可能的替代方法是设置最大维度(基于 QSplitter 方向),但这不完全相同。
如果拆分器中的所有小部件都有最大尺寸(包括只有 one 小部件存在的情况),结果是拆分器将根据这些小部件具有最大尺寸,具体取决于其他其布局中(或“上方”)的小部件,但如果拆分器是顶层 window 那么只要将其调整为大于其子项的最大值的大小时就会留下一些空白 space仁].