0

I have this code in which I create a number of QCheckBoxes through a loop:

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("My App")
        self.dbutton = QPushButton("Press ME")
        self.dbutton.setEnabled(False)
        self.button_state = 0

        self.checkbox_layout = QFormLayout()
        for i in range(5):
            self.checkbox = QCheckBox()
            self.checkbox.toggled.connect(self.enable_button)
            self.series_info = QLabel(str(i))
            self.checkbox_layout.addRow(self.checkbox, self.series_info)

        layout = QVBoxLayout()
        layout.addWidget(self.dbutton)
        layout.addLayout(self.checkbox_layout)

        widget = QWidget()
        widget.setLayout(layout)
        self.setCentralWidget(widget)

    def enable_button(self):
        print(self.checkbox.isChecked())

What I'm trying to do is to get the state of the specific QCheckBox that is triggering the signal to the enable_button slot, but I'm getting this weird behavior, where The state is show as False until all buttons are enable, but then it immediately flips to False as soon as just one of them is unmarked, as shown in the gif below. How can I fix this?

enter image description here

  • 1
    1. don't create instance attributes in a for loop, as it's completely pointless, since they'll be overwritten at every iteration and you'll always get the last created one; 2. use partials or lambdas: `checkbox.toggled.connect(lambda _, chk=chk: self.enable_button(chk))` and get the button by adding the argument to `def enable_button(self, chk):`; 3. similarly, use [`self.sender()`](//doc.qt.io/qt-5/qobject.html#sender) to get the object that emitted the signal, without the function argument; 4. add the button to an instance attribute list, and use `lambda _, i=i` to get its index as argument. – musicamante Apr 21 '23 at 05:14
  • 1
    Note that point 1 is the main issue in your code, because it makes no sense to create instance attributes with the same name reference in a for loop (unless you **really** know what you're doing). Creating `self.checkbox` in the for loop is completely pointless because it's just like doing `self.checkbox = QCheckBox()` over multiple lines: whenever you try to get `self.checkbox` *after* the for loop, it will always get the *last* created object to which that `self.checkbox` references to; simplifying: `x = 0; x = 1; x = 2; print(x)` will obviously print 2. – musicamante Apr 21 '23 at 05:21

0 Answers0