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_()
Try it:
from PyQt5.QtWidgets import QApplication, QWidget, QRadioButton, QHBoxLayout, QButtonGroup
import sys
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self._dictRB = { # +++
'rb1': False,
'rb2': False,
'rb3': False,
}
# Radio buttons
self.group = QButtonGroup()
self.b1 = QRadioButton('rb1') # + 'rb1'
self.group.addButton(self.b1)
# self.b1.clicked.connect(lambda: self.radioButtonClicked())
self.b2 = QRadioButton('rb2') # + 'rb2'
self.group.addButton(self.b2)
# self.b2.clicked.connect(lambda: self.radioButtonClicked())
self.b3 = QRadioButton('rb3') # +++
self.group.addButton(self.b3)
# Layout
self.layout = QHBoxLayout()
self.layout.addWidget(self.b1)
self.layout.addWidget(self.b2)
self.setLayout(self.layout)
self.group.buttonClicked.connect(self.check_button) # +++
def check_button(self, radioButton): # +++
if self._dictRB[radioButton.text()]:
self._dictRB[radioButton.text()] = False
self._dictRB['rb3'] = True
self.b3.setChecked(True)
else:
for b in self._dictRB:
self._dictRB[b] = False
self._dictRB[radioButton.text()] = True
print("clickеd button -> `{} - {}`".format(radioButton.text(), radioButton.isChecked()))
'''
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_()
def delectRadioButtons(self):
if self.radioButton_female.isCheckable() or self.radioButton_male.isCheckable():
self.radioButton_male.setChecked(True)
self.radioButton_female.setChecked(True)
self.radioButton_male.setCheckable(False)
self.radioButton_female.setCheckable(False)
self.radioButton_female.setCheckable(True)
self.radioButton_male.setCheckable(True)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.