取消选中独占组中的所有框

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)