【问题标题】:Change checkbox state to not checked when other checkbox is checked pyqt更改CheckBox状态,未选中其他复选框PyQt
【发布时间】:2016-07-16 19:40:33
【问题描述】:

我正在使用 Qt Designer 和 pyqt 代码来编写应用程序。

我有一个非常简单的问题:在我的 UI 中,我有 2 个复选框,我需要将第一个复选框设置为始终 未选中,而第二个复选框未选中 .

换句话说,第一个复选框只有在第二个复选框被选中时才能被选中,但如果第一个复选框没有被选中,第二个复选框也可以被选中。

在 Qt Designer 中,我还没有找到一种 简单 的方法来使用 Signals/Slots 函数。

我查看了 Qt API 并尝试编写一些代码:

class CreateRIVLayerDialog(QDialog, FORM_CLASS):
    def __init__(self, iface)

    # some more code here...

    if self.addCheckDB.isChecked():
        self.addCheck.setChecked(False)

但没有结果。

有人有什么提示吗?

谢谢

【问题讨论】:

    标签: qt checkbox pyqt


    【解决方案1】:

    只使用信号。当您说您不能通过设计器直接执行此操作时,您是正确的,因为您必须反转选中的属性。我想到的最简单和最易读的方法是使用一个公共插槽加上一个内部成员变量,该变量保持两者的检查状态:

    • 将self._toggle = INITIAL_VALUE 添加到您的班级 - INITIAL_VALUE 包含一个布尔值,您可以使用它来选中/取消选中您的复选框

        self._toggle = True
        self.check1 = QCheckBox('Check 1', self)
        self.check1.setChecked(self._toggle)
        self.check2 = QCheckBox('Check 2', self)
        self.check2.setChecked(not self._toggle)
      
    • 添加一个槽:

        @pyqtSlot()
        def toggle(self):
          self._toggle = not self._toggle
          self.check1.setChecked(self._toggle)
          self.check2.setChecked(not self._toggle)
      
    • 将两个复选框的clicked 信号连接到此插槽。

      警告!不要不要在此处使用stateChanged 信号,否则您将开始无限递归。 :3

        self.check1.clicked.connect(self.toggle)
        self.check2.clicked.connect(self.toggle)
      

    我在这里所做的基本上是接管两个复选框的状态更改,并使用第一个复选框的 self._toggle 的值和第二个复选框的 self._toggle 的反转值手动完成。

    如果您想在插槽内减少反转,尽管它的可读性较差,但以下方法也可以使用:

    @pyqtSlot()
    def toggle(self):
      self.check2.setChecked(self._toggle) # Old value of our check1 becomes the value of check2
      self._toggle = not self._toggle # Invert
      self.check1.setChecked(self._toggle) # New value is assigned to check1
    

    注意:您也可以在插槽内使用isChecked() 并在没有额外变量的情况下执行上述所有操作,但是我发现这更具可读性并且函数调用更少(每个isChecked() 和setChecked() 是一个函数调用)

    【讨论】:

    • 如果“很多”是指 3-4 行...当然。大声笑你不能在这里省略中间人(插槽),因为你想要一些自定义行为。如果是“每当我(取消)选中其中一个复选框时,我想同时(取消)选中两个复选框”,那么您将拥有更简单的解决方案,即直接连接它们的插槽和信号。据我所知,在没有处理信号的额外位置(插槽)的情况下反转信号的值是不可能的。也许有一个 lambda 函数...
    • 是的,如果check-uncheck状态应该同步,我想你可以简单地使用Qt Designer..我会试试你的代码,再次感谢!
    • Np,如果您有更多问题/建议/等。随时在这里发表评论。 :)
    【解决方案2】:

    最简单的方法是使用两个信号连接,其中一个可以在 Qt Designer 中完成。

    您的设计要求“只有在选中第二个复选框时才能选中第一个复选框”。这相当于说当第二个复选框未选中时,第一个复选框应该禁用。禁用该复选框可以让用户清楚地知道该选项不可用。

    所以在 Qt Designer 中,您应该将checkbox2 的toggled 信号连接到checkbox1 的setEnabled 插槽。 (可能还需要在 Qt Designer 中设置 checkbox1 的初始 enabled 状态。

    然后,在您的代码中,您应该进行第二次连接,如下所示:

        self.checkbox2.toggled.connect(
            lambda checked: not checked and self.checkbox1.setChecked(False))
    

    这将在 checkbox2 未选中时清除 checkbox1 的选中状态。

    如果你想在代码中完成整个事情,它看起来像这样:

        self.checkbox1.setEnabled(False)
        self.checkbox2.toggled.connect(self.checkbox1.setEnabled)
        self.checkbox2.toggled.connect(
            lambda checked: not checked and self.checkbox1.setChecked(False))
    

    【讨论】:

    • @ekhmoro。感谢您的快速方法!很奇怪,您不能轻松地使用信号/插槽系统更改复选框状态(检查或不检查)。但是用你的代码就可以了
    • @matteo。这对我来说一点也不奇怪。您要求一个小部件的状态以一种非常特定的方式依赖于另一个小部件。我认为你得到的两个答案表明 pyqt 让这件事变得尽可能简单。
    • setChecked(...) 从类型的角度来看是不正确的调用...您在使用类型时应该小心。 Python 中没有编译器。因此,如果您使用 PyQt,有两种方法:查看 API 的原始签名 (doc.qt.io/qt-5/qcheckbox.html#setCheckState) 或使用部分准备好的 PyQt 文档来获取您正在使用的版本:riverbankcomputing.com/static/Docs/PyQt5/api/qtwidgets/… p.s.在大型项目中要小心,缺少类型和编译器只是令人头疼。
    【解决方案3】:

    我知道我参加这个聚会迟到了,但有一种方法可以更轻松地完成这件事,而且我认为最初的人想要什么。干得好。如果您有一个 checkbox_1 并且您选中/取消选中它,它将连接到以下函数。

    def Change_the_Checkbox_Function(self):
        if self.checkbox_1.isChecked(): 
            if self.checkbox_2.isChecked():
                pass
            else:
                self.checkbox_2.setChecked(True)
        else:
            self.checkbox_2.setChecked(False)
    

    如果您希望 checkbox_1 选中或取消选中许多其他复选框(如全选),则不是 checkbox_1 直接调用上述函数,而是另一个调用其他函数来选中/取消选中框的函数,如下所示:

    def Select_ALL_checkboxes(self):
        self.Change_the_Checkbox_1_Function()
        self.Change_the_Checkbox_2_Function()
        self.Change_the_Checkbox_3_Function()
    
        ....etc
    

    对我来说,这是最合乎逻辑的方式,而且没有太多技术性。它运行良好且速度很快。可能不是最有效或最漂亮的,但我发现这是一次选中/取消选中多个复选框的最佳方式。

    【讨论】:

      猜你喜欢
      • 2019-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-27
      • 1970-01-01
      • 1970-01-01
      • 2015-02-16
      • 1970-01-01
      相关资源
      最近更新 更多