问题
I'm trying to make a widget which contains many other widgets and I keep having problems with resizing the window: the widget keeps expanding even if I "tell" it not to. Here is my minimal example:
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_()
This code does work however if I resize the window then all the buttons and labels get spread out over the screen which is not what I want.
I've tried:
Setting a fixed size: doesn't work because the label text can be different lengths and I want the widget to resize accordingly (but stay as small as possible)
self.setFixedSize(self.size())
doesn't do anything and sometimes makes it worseself.setSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
or any other size policy seems to do nothing
TL;DR I want my widget to shrink even if there's empty space but I don't want to set a fixed size.
EDIT:
I have partially solved the problem by passing in alignment=QtCore.Qt.AlignLeft
to all the self.layout.addWidget
calls. It doesn't totally get rid of the problem however it may be a step in the right direction.
回答1:
If you want to keep those widgets as small as possible, you can add a row and column stretch to the layout, set for a row/column index greater than the most bottom-right layout coordinate used.
In your case, you have two rows and two columns, so it's enough to set the stretch for the third row and column:
self.layout.setColumnStretch(2, 1)
self.layout.setRowStretch(2, 1)
Obviously, you can set it for a very high index, so that if you have to add more widgets you don't have to care about it.
If you want to keep those widgets in the center, just add them starting from the second row and column and set the row/column stretch for the first row/column too:
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)
Note that you can also use the size policy, but you have to use Maximum
, not Minimum
, and you also need to add widgets with the correct alignment.
回答2:
I got same issue. I resolved the issue by setting the values of minimum and maximum size to equal like both to 100
If you want to shrink the widget set minimum to 0 and set maximum value to the size you want start the display. It will not expand but shrink
回答3:
From what you are describing it seems you just don't want to use a layout.
Make a widget with a layout to hold the buttons and label. Place this widget in the main window without using a layout, instead place with setGeometry.
Something like this,
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_()
Notice that not using a layout is, in most cases, not advised as it makes managing the window harder.
来源:https://stackoverflow.com/questions/62657281/how-do-i-stop-a-custom-widget-from-expanding-in-pyqt5