Search code examples
pythonpyqtpyqt5qpushbutton

Decreasing distance between text and edge for QPushButton?


How can we decrease the distance between the text strings inside of a QPushButton and the edge?

For me (on LXDE) it now looks like this:

buttons-actual

self.on_qpb = QtWidgets.QPushButton(self.tr("On"))
hbox.addWidget(self.on_qpb)
self.on_qpb.setCheckable(True)
self.on_qpb.toggled.connect(self.on_on_toggled)

We're hoping for something like this:

buttons-wanted

We achieved the latter using setFixedWidth but that creates problems when translating into other languages

What can you recommend? Grateful for help!


Solution

  • A possible solution is to set the width of the text according to the text with the help of QFontMetrics, or you can create a class that implements the logic with size policies and return an appropriate sizeHint() as shown in the following example:

    from PyQt5.QtCore import *
    from PyQt5.QtWidgets import *
    
    class PushButton(QPushButton):
        def __init__(self, *args, **kwargs):
            QPushButton.__init__(self, *args, **kwargs)
            self.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)
    
        def sizeHint(self):
            w = self.fontMetrics().width(" {} ".format(self.text()))
            h = QPushButton.sizeHint(self).height()
            return QSize(w, h)
    
    
    class Widget(QWidget):
        def __init__(self, *args, **kwargs):
            QWidget.__init__(self, *args, **kwargs)
            hbox = QHBoxLayout(self)
    
            self.on_qpb = QPushButton(self.tr("On"))
            self.on_qpb.setCheckable(True)
            self.on_qpb.setFixedWidth(self.on_qpb.fontMetrics().width(" {} ".format(self.on_qpb.text())))
    
            self.off_qpb = PushButton(self.tr("Off"))
            self.off_qpb.setCheckable(True)
    
            hbox.addWidget(self.on_qpb)
            hbox.addWidget(self.off_qpb)
    
    if __name__ == '__main__':
        import sys
    
        app = QApplication(sys.argv)
        w = Widget()
        w.show()
        sys.exit(app.exec_())