我在 pyQt5 中的 QButtonGroup 中使用了一些 QRadioButtons。我希望用户能够选择其中一个独占的选项或不选择,所以如果他不小心点击了一个单选按钮,他应该能够再次点击它来取消选中它。
我目前的方法是将点击的方法连接到一个自定义的函数,以检查按钮的状态,但我想不出如何用一种简单的方法来实现,而不使用阴暗的点击计数器。
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_()
试试吧。
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_()
最后,我想出了一个解决方案,分两步走:第一,让按钮组不具有独占性,这样按钮再被点击时就可以取消勾选。第二,当一个单选题被选中时,取消勾选其他每一个按钮。
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_()