I'm using some QRadioButtons inside a QButtonGroup in pyQt5. I would like the user to be able to select one of the exclusive options or none, so if he accidentally clicks a radio button, he should be able to click it again to uncheck it.
My current approach is to connect the clicked method to a custom function that checks the button status, but I couldn't figure how to do it in a simple way, without using shady click counters.
from PyQt5.QtWidgets import QApplication, QWidget, QRadioButton, QHBoxLayout, QButtonGroup
import sys
class MainWindow(QWidget):
def __init__(self):
super().__init__()
# Radio buttons
self.group = QButtonGroup()
self.b1 = QRadioButton()
self.group.addButton(self.b1)
self.b1.clicked.connect(lambda: self.radioButtonClicked())
self.b2 = QRadioButton()
self.group.addButton(self.b2)
self.b2.clicked.connect(lambda: self.radioButtonClicked())
# Layout
self.layout = QHBoxLayout()
self.layout.addWidget(self.b1)
self.layout.addWidget(self.b2)
self.setLayout(self.layout)
def radioButtonClicked(self):
if self.sender().isChecked():
self.sender().setAutoExclusive(False)
self.sender().setChecked(False) # This is not working, as it fires on the first click
self.sender().setAutoExclusive(True)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()
Finally, I've come with a solution in two steps: first, make the button group not exclusive, so buttons can be unchecked when clicked again. And second, when a radio is selected, uncheck every other button.
from PyQt5.QtWidgets import (QApplication, QWidget, QRadioButton,QHBoxLayout, QButtonGroup)
import sys
class MainWindow(QWidget):
def __init__(self):
super().__init__()
# Radio buttons
self.group = QButtonGroup()
self.group.setExclusive(False) # Radio buttons are not exclusive
self.group.buttonClicked.connect(self.check_buttons)
self.b1 = QRadioButton()
self.group.addButton(self.b1)
self.b2 = QRadioButton()
self.group.addButton(self.b2)
# Layout
self.layout = QHBoxLayout()
self.layout.addWidget(self.b1)
self.layout.addWidget(self.b2)
self.setLayout(self.layout)
def check_buttons(self, radioButton):
# Uncheck every other button in this group
for button in self.group.buttons():
if button is not radioButton:
button.setChecked(False)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()