问题
Is there any way to reliably have a push button's height fit to its contents? Some previous answers suggest using layouts and size policies, or maximum height (How to make height of a QPushButton automatically fit the text?, Increase Height of QPushButton in PyQT, How can I set a QPushButton to grow vertically?), but they don't seem to work for me.
See the example below. The two buttons are drawn with their default "one line" height, so the text inside is clipped. Setting their size policies as Preferred
or Minimum
doesn't change anything. Using addStretch
instead of setAlignment
doesn't change anything (using none makes the buttons stretch to fill the window, which is not what I want). Changing the minimum height works, but that's far from practical, unless there's some way to automatically compute and set it.
#!/usr/bin/env python3
import sys
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import *
from PyQt5.QtCore import QSize
class HelloWindow(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
button1 = QPushButton()
l = QVBoxLayout()
l.addWidget(QLabel('One'))
l.addWidget(QLabel('Description of button one'))
button1.setLayout(l)
#button1.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
#button1.setMinimumHeight(50)
button2 = QPushButton()
l = QVBoxLayout()
l.addWidget(QLabel('Two'))
l.addWidget(QLabel('Description of button two\nwith extra line'))
button2.setLayout(l)
#button2.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
#button2.setMinimumHeight(65)
layout = QVBoxLayout()
layout.addWidget(button1)
layout.addWidget(button2)
#layout.addStretch(1)
layout.setAlignment(QtCore.Qt.AlignTop)
centralWidget = QWidget(self)
centralWidget.setLayout(layout)
self.setCentralWidget(centralWidget)
self.resize(200, 400)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
mainWin = HelloWindow()
mainWin.show()
sys.exit( app.exec_() )
回答1:
The problem is that a push button normally has no layout, and returns a size hint based on the following:
- the contents, if they exist (the icon and/or the text)
- the metrics of the current style (the button bevel, the focus rectangle and the button margins) based on the contents, returned from QStyle.sizeFromContents()
In your case, the simplest solution would be to simply use the new line character for the button text (for example: 'One\nDescription of button one'
), but if you want to add a widget that is not a label (or want to have more control over the label itself), you must override the sizeHint
:
class ResizableButton(QtWidgets.QPushButton):
def sizeHint(self):
if self.layout():
# the button now has a layout, return its size hint
return self.layout().sizeHint()
# no layout set, return the result of the default implementation
return super().sizeHint()
来源:https://stackoverflow.com/questions/61571582/qt-qpushbutton-vertical-size-fit-to-contents