如何将 QStackedWidget 大小设置为子窗口小部件的最小大小?

How to set QStackedWidget size to child widgets minimum size?

无法使本例中的 QLabel 达到包含其文本的最小尺寸。我需要布局和堆叠的小部件,然后将其自身调整为适合标签所需的最小尺寸。

我已使用 https://www.tutorialspoint.com/pyqt/pyqt_qstackedwidget.htm 中的代码来演示我的问题。

设置大小策略似乎在应用程序启动时起作用,但增加应用程序宽度最终会导致标签在列表达到一定宽度后展开。

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *


class stackedExample(QWidget):

    def __init__(self):
        super(stackedExample, self).__init__()
        self.rightlist = QListWidget()
        self.rightlist.setSizePolicy(QSizePolicy.Expanding,QSizePolicy.Expanding)

        self.rightlist.insertItem(0, 'Contact')

        self.stack1 = QWidget()
        self.stack1.setSizePolicy(QSizePolicy.Minimum,QSizePolicy.Minimum)

        self.stack1UI()

        self.Stack = QStackedWidget(self)
        self.Stack.setSizePolicy(QSizePolicy.Minimum,QSizePolicy.Minimum)
        self.Stack.addWidget(self.stack1)

        hbox = QHBoxLayout(self)
        hbox.addWidget(self.Stack)
        hbox.addWidget(self.rightlist)


        self.setLayout(hbox)
        self.rightlist.currentRowChanged.connect(self.display)
        self.setGeometry(300, 50, 10, 10)
        self.setWindowTitle('StackedWidget demo')
        self.show()


    def stack1UI(self):
        layout = QVBoxLayout()
        label = QLabel("Hello World")
        label.setSizePolicy(QSizePolicy.Minimum,QSizePolicy.Minimum)
        label.setStyleSheet("QLabel { background-color : red; color : blue; }")
        layout.addWidget(label)
        self.stack1.setLayout(layout)


    def display(self, i):
        self.Stack.setCurrentIndex(i)

def main():
    app = QApplication(sys.argv)
    ex = stackedExample()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

不确定这是否是正确的方法,但添加拉伸因子似乎已经实现了我想要的。

hbox.addWidget(self.rightlist, stretch=1)

tl;博士

删除除 QStackedWidget 之外的所有内容的大小策略设置(您必须将水平策略设置为 Maximum),一切都应该没问题。

说明

不得不承认:我一直觉得QSizePolicy 枚举名称很混乱(我知道我不是唯一一个),所以我很同情你的疑惑。

设置拉伸只能部分解决问题,因为有时您可能需要或想要手动设置拉伸,这可能会影响某些尺寸政策。

问题是您将大小策略设置为 "Minimum",正如 QSizePolicy documentation 所解释的那样:

The sizeHint() is minimal, and sufficient. The widget can be expanded [...]

那是因为 Minimum 使用 GrowFlag.
这意味着,如果布局 "thinks" 有一些可用的 space 小部件,它将让它扩展: Minimum 并不意味着小部件将使用它的最小尺寸(或者,更好的是 minimumSizeHint()),但它将使用 sizeHint() 作为布局的最小尺寸,同时保持其容量为 expand;如果有可用的 space,它将使用它。

您真正需要的是将水平策略设置为 Maximum,具体来说,设置为 Stack 对象 only(QStackWidget,不是 QWidget 容器,也不是 QLabel)。
那是因为 Maximum 实际上使用了 ShrinkFlag (同样来自 QSizePolicy 文档):

The sizeHint() is a maximum. The widget can be shrunk any amount without detriment if other widgets need the space (e.g. a separator line). It cannot be larger than the size provided by sizeHint().

也就是说,请注意,在某些情况下,QLabel 存在已知问题,特别是如果标签有自动换行。