取消选中独占组中的所有框
Uncheck all boxes in exclusive group
我有两个复选框,它们属于一个按钮组。我希望能够 select 一个,另一个,或者 none。为此,我有以下几点:
import sys
from PySide2 import QtCore, QtWidgets
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle('Check Problems')
self.init_widgets()
self.init_layout()
def init_widgets(self):
self.check1_label = QtWidgets.QLabel('Check1')
self.check1 = QtWidgets.QCheckBox()
self.check2_label = QtWidgets.QLabel('Check2')
self.check2 = QtWidgets.QCheckBox()
self.check_buttongroup = QtWidgets.QButtonGroup()
self.check_buttongroup.addButton(self.check1)
self.check_buttongroup.addButton(self.check2)
self.check_buttongroup.buttonPressed.connect(self.check_buttongroup_pressed)
def init_layout(self):
check1_layout = QtWidgets.QHBoxLayout()
check1_layout.addWidget(self.check1_label)
check1_layout.addWidget(self.check1)
check2_layout = QtWidgets.QHBoxLayout()
check2_layout.addWidget(self.check2_label)
check2_layout.addWidget(self.check2)
check_layout = QtWidgets.QVBoxLayout()
check_layout.addLayout(check1_layout)
check_layout.addLayout(check2_layout)
# Central widget
centralWidget = QtWidgets.QWidget()
centralWidget.setLayout(check_layout)
self.setCentralWidget(centralWidget)
def check_buttongroup_pressed(self, button):
print('\nIs this check1? ', button == self.check1, flush=True)
print('Status when pressed: ', button.isChecked(), flush=True)
if button.isChecked():
print('Button isChecked: ', button.isChecked(), flush=True)
print('Changing button check state...', flush=True)
button.group().setExclusive(False)
button.setChecked(False)
print('Button isChecked: ', button.isChecked(), flush=True)
button.group().setExclusive(True)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
mainWin = MainWindow()
mainWin.show()
sys.exit(app.exec_())
最初没有选中任何框。单击 check1
会产生:
Is this check1? True
Status when pressed: False
这是意料之中的。该框最初未选中。但是,单击它后,该框现在已选中。当我再次单击 check1
时,我希望它取消选中,从而使两个框都未选中。现在,点击 check1
,我看到:
Is this check1? True
Status when pressed: True
Button isChecked: True
Changing button check state...
Button isChecked: False
这符合预期。然而,令人意想不到的是,check1
仍然被选中!
第三次点击产生:
Is this check1? True
Status when pressed: True
Button isChecked: True
Changing button check state...
Button isChecked: False
为什么 check1
没有按预期取消选中? button.isChecked()
是在骗我,还是 setChecked(False)
没有做好它的工作?我是不是哪里弄错了?
我已经用 PySide2==5.15.0、PySide2==5.13、PySide6 和 PyQt5==5.15 尝试过,结果相同,所以我认为这是它应该的行为方式,而不是一些 Qt 实现错误.
解决方案是,如果在发出 buttonPressed 信号时选中按钮,则将 属性 exclusive 更改为 False,并在发出 buttonClicked 时将 属性 设置为 true。
def init_widgets(self):
# ...
self.check_buttongroup = QtWidgets.QButtonGroup()
self.check_buttongroup.addButton(self.check1)
self.check_buttongroup.addButton(self.check2)
self.check_buttongroup.buttonPressed.connect(self.handle_pressed)
self.check_buttongroup.buttonClicked.connect(self.handle_clicked)
def handle_pressed(self, button):
button.group().setExclusive(not button.isChecked())
def handle_clicked(self, button):
button.group().setExclusive(True)
我有两个复选框,它们属于一个按钮组。我希望能够 select 一个,另一个,或者 none。为此,我有以下几点:
import sys
from PySide2 import QtCore, QtWidgets
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle('Check Problems')
self.init_widgets()
self.init_layout()
def init_widgets(self):
self.check1_label = QtWidgets.QLabel('Check1')
self.check1 = QtWidgets.QCheckBox()
self.check2_label = QtWidgets.QLabel('Check2')
self.check2 = QtWidgets.QCheckBox()
self.check_buttongroup = QtWidgets.QButtonGroup()
self.check_buttongroup.addButton(self.check1)
self.check_buttongroup.addButton(self.check2)
self.check_buttongroup.buttonPressed.connect(self.check_buttongroup_pressed)
def init_layout(self):
check1_layout = QtWidgets.QHBoxLayout()
check1_layout.addWidget(self.check1_label)
check1_layout.addWidget(self.check1)
check2_layout = QtWidgets.QHBoxLayout()
check2_layout.addWidget(self.check2_label)
check2_layout.addWidget(self.check2)
check_layout = QtWidgets.QVBoxLayout()
check_layout.addLayout(check1_layout)
check_layout.addLayout(check2_layout)
# Central widget
centralWidget = QtWidgets.QWidget()
centralWidget.setLayout(check_layout)
self.setCentralWidget(centralWidget)
def check_buttongroup_pressed(self, button):
print('\nIs this check1? ', button == self.check1, flush=True)
print('Status when pressed: ', button.isChecked(), flush=True)
if button.isChecked():
print('Button isChecked: ', button.isChecked(), flush=True)
print('Changing button check state...', flush=True)
button.group().setExclusive(False)
button.setChecked(False)
print('Button isChecked: ', button.isChecked(), flush=True)
button.group().setExclusive(True)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
mainWin = MainWindow()
mainWin.show()
sys.exit(app.exec_())
最初没有选中任何框。单击 check1
会产生:
Is this check1? True
Status when pressed: False
这是意料之中的。该框最初未选中。但是,单击它后,该框现在已选中。当我再次单击 check1
时,我希望它取消选中,从而使两个框都未选中。现在,点击 check1
,我看到:
Is this check1? True
Status when pressed: True
Button isChecked: True
Changing button check state...
Button isChecked: False
这符合预期。然而,令人意想不到的是,check1
仍然被选中!
第三次点击产生:
Is this check1? True
Status when pressed: True
Button isChecked: True
Changing button check state...
Button isChecked: False
为什么 check1
没有按预期取消选中? button.isChecked()
是在骗我,还是 setChecked(False)
没有做好它的工作?我是不是哪里弄错了?
我已经用 PySide2==5.15.0、PySide2==5.13、PySide6 和 PyQt5==5.15 尝试过,结果相同,所以我认为这是它应该的行为方式,而不是一些 Qt 实现错误.
解决方案是,如果在发出 buttonPressed 信号时选中按钮,则将 属性 exclusive 更改为 False,并在发出 buttonClicked 时将 属性 设置为 true。
def init_widgets(self):
# ...
self.check_buttongroup = QtWidgets.QButtonGroup()
self.check_buttongroup.addButton(self.check1)
self.check_buttongroup.addButton(self.check2)
self.check_buttongroup.buttonPressed.connect(self.handle_pressed)
self.check_buttongroup.buttonClicked.connect(self.handle_clicked)
def handle_pressed(self, button):
button.group().setExclusive(not button.isChecked())
def handle_clicked(self, button):
button.group().setExclusive(True)