【问题标题】:Toggling a QRadioButton in pyqt5: uncheck when a checked radio button is clicked在pyqt5中切换QRadioButton:单击选中的单选按钮时取消选中
【发布时间】:2020-10-05 07:59:48
【问题描述】:

我在 pyQt5 的 QButtonGroup 中使用了一些 QRadioButtons。我希望用户能够选择一个独占选项或不选择,所以如果他不小心单击了一个单选按钮,他应该能够再次单击它以取消选中它。

我目前的方法是将 clicked 方法连接到检查按钮状态的自定义函数,但我不知道如何以简单的方式执行此操作,而不使用可疑的点击计数器。

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_()

【问题讨论】:

  • 对不起,你为什么不用QCheckBox?
  • @S.Nick 用户应该只能选择一个选项(或无)。我不知道这是否可以通过 QCheckBox 实现(我猜是这样),但即使是这样,我认为用户倾向于将检查排他性与圆形单选按钮联系起来,而不是方形复选框。当然,这只是一种意见,我愿意讨论。

标签: python pyqt qradiobutton


【解决方案1】:

最后,我提出了一个分两步的解决方案:首先,使按钮组不具有排他性,这样再次单击时可以取消选中按钮。第二,选择无线电时,取消选中每个其他按钮。

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_()

【讨论】:

  • 我认为有更好的方法。你也可以在check_buttons(self, radioButton, radioGroup) 中传递组,这样这个函数就可以为即将到来的 QButtonGroup 重用,完全不依赖于任何类变量
【解决方案2】:

试试看:

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_()

【讨论】:

  • 对不起,我想我们可能生活在不同的时区,昨天我不得不去睡觉。我只是在尝试你的代码,但尽管它有效,但它存在一个问题:我不能在单选按钮中使用文本,而且我会有很多收音机,所以保留那个 dict 对我来说似乎有点太多了。但无论如何感谢您的解决方案。但是我找到了我刚刚发布的另一个解决方案。
【解决方案3】:

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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-19
    • 1970-01-01
    • 2011-06-24
    • 1970-01-01
    • 2013-11-22
    相关资源
    最近更新 更多