Qt: QPushButton vertical size, fit to contents?

谁都会走 提交于 2021-01-29 16:26:32

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!