Search code examples
pythonpyqtpyqt5qradiobutton

How to format QRadioButton without label


Currently, the radiobutton widget is formatted this way:

enter image description here

I want to get rid of the text completely, and center the indicator inside it's widget. So that it looks like this:

enter image description here

What do I need to do to format the widget this way? I am using the editor, but certain chunks of my code are handwritten, so I would prefer that the answer work between both. Thanks!


Solution

  • You must use a QProxyStyle to move the position of the QRadioButton indicator:

    import sys
    
    from PyQt5 import QtCore, QtWidgets
    
    
    class ProxyStyle(QtWidgets.QProxyStyle):
        def subElementRect(self, element, option, widget):
            r = super().subElementRect(element, option, widget)
            if element in (
                QtWidgets.QStyle.SE_RadioButtonIndicator,
                QtWidgets.QStyle.SE_RadioButtonFocusRect,
                QtWidgets.QStyle.SE_RadioButtonClickRect,
            ):
                r.moveCenter(option.rect.center())
            return r
    
    
    if __name__ == "__main__":
        app = QtWidgets.QApplication(sys.argv)
    
        app.setStyle(ProxyStyle())
    
        w = QtWidgets.QWidget()
        lay = QtWidgets.QHBoxLayout(w)
    
        for _ in range(3):
            btn = QtWidgets.QRadioButton()
            btn.setStyleSheet("background-color: palette(button);")
            btn.setSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
            lay.addWidget(btn)
    
        w.resize(320, 240)
        w.show()
    
        sys.exit(app.exec_())
    

    enter image description here

    Update:

    This change can not be observed in Qt Designer so you will have to use code, for example:

    ├── main.py
    └── mainwindow.ui
    

    mainwindow.ui

    <?xml version="1.0" encoding="UTF-8"?>
    <ui version="4.0">
     <class>MainWindow</class>
     <widget class="QMainWindow" name="MainWindow">
      <property name="geometry">
       <rect>
        <x>0</x>
        <y>0</y>
        <width>800</width>
        <height>600</height>
       </rect>
      </property>
      <property name="windowTitle">
       <string>MainWindow</string>
      </property>
      <widget class="QWidget" name="centralwidget">
       <widget class="QRadioButton" name="radioButton">
        <property name="geometry">
         <rect>
          <x>130</x>
          <y>120</y>
          <width>221</width>
          <height>221</height>
         </rect>
        </property>
        <property name="styleSheet">
         <string notr="true">background-color: rgb(252, 233, 79);</string>
        </property>
        <property name="text">
         <string/>
        </property>
       </widget>
      </widget>
      <widget class="QMenuBar" name="menubar">
       <property name="geometry">
        <rect>
         <x>0</x>
         <y>0</y>
         <width>800</width>
         <height>24</height>
        </rect>
       </property>
      </widget>
      <widget class="QStatusBar" name="statusbar"/>
     </widget>
     <resources/>
     <connections/>
    </ui>
    

    main.py

    import os
    import sys
    
    from PyQt5 import QtCore, QtGui, QtWidgets, uic
    
    
    CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
    
    
    class ProxyStyle(QtWidgets.QProxyStyle):
        def subElementRect(self, element, option, widget):
            r = super().subElementRect(element, option, widget)
            if element in (
                QtWidgets.QStyle.SE_RadioButtonIndicator,
                QtWidgets.QStyle.SE_RadioButtonFocusRect,
                QtWidgets.QStyle.SE_RadioButtonClickRect,
            ):
                r.moveCenter(option.rect.center())
            return r
    
    
    if __name__ == "__main__":
    
        app = QtWidgets.QApplication(sys.argv)
        app.setStyle(ProxyStyle())
        w = uic.loadUi(os.path.join(CURRENT_DIR, "mainwindow.ui"))
        w.show()
        sys.exit(app.exec_())
    

    Output:

    enter image description here

    Note: I added a background color to the QRadioButton so that the position can be distinguished.