如何阻止自定义小部件在 PyQt5 中展开?

How do I stop a custom widget from expanding in PyQt5?

我正在尝试制作一个包含许多其他小部件的小部件,但我在调整 window 的大小时一直遇到问题:即使我“告诉”它不要扩展,小部件也会继续扩展。这是我的最小示例:

from PyQt5 import QtWidgets, QtGui, QtCore

class CustomWidget(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.layout  = QtWidgets.QGridLayout()
        self.button1 = QtWidgets.QPushButton("Button A")
        self.button2 = QtWidgets.QPushButton("Button B")
        self.label1  = QtWidgets.QLabel("Long label that can span multiple columns")

        self.layout.addWidget(self.button1, 0, 0)
        self.layout.addWidget(self.button2, 0, 1)
        self.layout.addWidget(self.label1, 1, 0, 1, 2)
        self.setLayout(self.layout)


class App(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.cw = CustomWidget()
        self.layout = QtWidgets.QVBoxLayout()
        self.layout.addWidget(self.cw)

        self.setLayout(self.layout)
        self.show()

QtWidgets.QApplication.setStyle(QtWidgets.QStyleFactory.create("Fusion"))
app = QtWidgets.QApplication([])
win = App()
status = app.exec_()

这段代码确实有效,但是如果我调整 window 的大小,那么所有按钮和标签都会散布在屏幕上,这不是我想要的。

我试过:

TL;DR 我希望我的小部件即使是空的也能缩小 space 但我不想设置固定大小。

编辑:

我通过将 alignment=QtCore.Qt.AlignLeft 传递给所有 self.layout.addWidget 调用,部分 解决了问题。它并没有完全解决这个问题,但它可能是朝着正确方向迈出的一步。

我遇到了同样的问题。我通过将最小和最大大小的值设置为等于 100

来解决这个问题

如果要缩小小部件,请将最小值设置为 0,并将最大值设置为您想要的大小,然后开始显示。不扩反缩

根据您的描述,您似乎只是不想使用布局。

制作一个带有布局的小部件来放置按钮和标签。将此小部件放置在主 window 中而不使用布局,而是使用 setGeometry 放置。

像这样,

from PyQt5 import QtWidgets, QtGui, QtCore

class CustomWidget(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.resize(400, 100)
        
        # Create a widget to hold your buttons
        self.fixwidget = QtWidgets.QWidget(self)
        
        self.layout  = QtWidgets.QGridLayout()
        self.button1 = QtWidgets.QPushButton("Button A")
        self.button2 = QtWidgets.QPushButton("Button B")
        self.label1  = QtWidgets.QLabel("Long label that can span multiple columns")

        self.layout.addWidget(self.button1, 0, 0)
        self.layout.addWidget(self.button2, 0, 1)
        self.layout.addWidget(self.label1, 1, 0, 1, 2)
        
        # set the layout inside the widget
        self.fixwidget.setLayout(self.layout) 
        
        # place the widget with setGeometry
        height = self.fixwidget.sizeHint().height()
        width = self.fixwidget.sizeHint().width()
        xpos, ypos = 5, 5
        self.fixwidget.setGeometry(QtCore.QRect(xpos, ypos, width, height))


QtWidgets.QApplication.setStyle(QtWidgets.QStyleFactory.create("Fusion"))
app = QtWidgets.QApplication([])
win = CustomWidget()
win.show()
status = app.exec_()

请注意,在大多数情况下,不建议不使用布局,因为这会使管理 window 变得更加困难。

如果您想使这些小部件尽可能小,您可以向布局添加行和列拉伸,设置 row/column 索引大于所用的最右下角布局坐标。

在你的例子中,你有两行两列,所以设置第三行和第三列的拉伸就足够了:

    self.layout.setColumnStretch(2, 1)
    self.layout.setRowStretch(2, 1)

显然,您可以将其设置为非常高的索引,这样,如果您必须添加更多小部件,则不必关心它。

如果您想将这些小部件保留在中心,只需从第二行和第二列开始添加它们,并为第一个 row/column 也设置 row/column 拉伸:

    self.layout.setColumnStretch(0, 1)
    self.layout.setRowStretch(0, 1)
    self.layout.addWidget(self.button1, 1, 1)
    self.layout.addWidget(self.button2, 1, 2)
    self.layout.addWidget(self.label1, 2, 1, 1, 2)
    self.layout.setColumnStretch(3, 1)
    self.layout.setRowStretch(3, 1)

请注意,您也可以使用大小策略,但您必须使用 Maximum,而不是 Minimum,并且您还需要添加具有正确对齐方式的小部件。