取消选中单选按钮 - PyQt4

3 投票
2 回答
11603 浏览
提问于 2025-04-17 09:20

在这段代码示例中:

from PyQt4.QtGui import QDialog, QPushButton, QRadioButton, QHBoxLayout, QApplication, QButtonGroup
import sys

class Form(QDialog):
    def __init__(self, parent=None):
        super(Form, self).__init__(parent=None)

        button = QPushButton('Button')
        self.radiobutton1 = QRadioButton('1')
        self.radiobutton2 = QRadioButton('2')
        #self.group = QButtonGroup()
        #self.group.addButton(self.radiobutton1)
        #self.group.addButton(self.radiobutton2)       
        #self.group.setExclusive(False)

        layout = QHBoxLayout()
        layout.addWidget(button)
        layout.addWidget(self.radiobutton1)
        layout.addWidget(self.radiobutton2)
        self.setLayout(layout)

        button.clicked.connect(self.my_method)

    def my_method(self):
        self.radiobutton1.setChecked(False)
        self.radiobutton2.setChecked(False)

app = QApplication(sys.argv)
form = Form()
form.show()
app.exec_()

当我点击按钮时,我希望选中的单选按钮能够取消选中,但这从来没有发生过。如果我把注释的那几行去掉,然后运行代码,我就可以取消选中单选按钮了。但是又出现了另一个问题。因为这个组不是互斥的,我可以把两个单选按钮都选中,这可不应该发生。

我该怎么做才能在一次只能选中一个按钮的情况下,取消选中按钮呢?

2 个回答

1

如果你在找一个简单的方法来解决这个让人烦恼的问题,可以把每个按钮连接到一个 slot,这个 slot 用来控制其他按钮的 CheckState(选中状态)。

只需要把你想要的按钮放到一个 QButtonGroup 里,获取按钮列表,检查一下 sender(发送者)是不是当前按钮,如果不是,就把其他按钮取消选中。

假设你是在一个循环里创建按钮,这样做就很简单了:

self.bg = QButtonGroup()
self.bg.setExclusive(False)

for button in list_of_buttons:
    self.bg.addButton(button)
    button.clicked.connect(self.uncheck_other_buttons)


def uncheck_other_btns(self):
    for button in self.bg.buttons():  # returns the list of all added buttons
        if self.sender() != button:   # in PyQt5, button.objectName() fails if name isn't set, 
                                      # instead, simply check that the signal sender() object  
                                      # is not the same object as the clicked button
            button.setChecked(False)  # then set all other buttons to be unchecked
7

这感觉有点像作弊,但确实有效:

import sys
import PyQt4.QtGui as QtGui

class Form(QtGui.QDialog):
    def __init__(self, parent=None):
        super(Form, self).__init__(parent)

        button = QtGui.QPushButton('Button')
        button.clicked.connect(self.my_method)

        self.radiobutton1 = QtGui.QRadioButton('1')
        self.radiobutton2 = QtGui.QRadioButton('2')

        layout = QtGui.QHBoxLayout()
        layout.addWidget(button)
        layout.addWidget(self.radiobutton1)
        layout.addWidget(self.radiobutton2)
        self.setLayout(layout)

        self.group = QtGui.QButtonGroup()
        self.group.addButton(self.radiobutton1)
        self.group.addButton(self.radiobutton2)       

    def my_method(self):
        self.group.setExclusive(False)        
        self.radiobutton1.setChecked(False)
        self.radiobutton2.setChecked(False)
        self.group.setExclusive(True)

app = QtGui.QApplication(sys.argv)
form = Form()
form.show()
app.exec_()

正如你所提到的,当 self.group.setExclusive(False) 被设置时,你可以同时取消选中两个单选按钮。

而当 self.group.setExclusive(True) 时,只能选中一个单选按钮。

所以 my_method 只是简单地调用 self.group.setExclusive(False),这样就可以取消选中两个单选按钮,然后再设置回 self.group.setExclusive(True)


附言:我觉得这一行中的 parent 不应该设置为 None

super(Form, self).__init__(parent = None)

因为如果传给 Formparent 不是空的,你可能想把这个 parent 传给 QDialog.__init__

撰写回答