1

I am currently using PyQt5 to develop a GUI for my application. I have not used PyQt for very long and I am currently still learning more about it. I have discovered a way to dynamically create a QCheckBox for every element in a specified list and add it to my QGridLayout. I am currently attempting to connect a function to each of the generated QCheckBoxes. My code is as follows:

import sys
from PyQt5.QtWidgets import (QWidget, QGridLayout,
    QPushButton, QApplication, QCheckBox, QButtonGroup, QAbstractButton)

class Example(QWidget):

    def __init__(self):
        super().__init__()

        self.initUI()

    def checkboxState(self,b):
        if b.isChecked() == True:
            print(b.text()+ " is selected")
        else:
            print(b.text()+ " is deselcted")

    def initUI(self):

        grid = QGridLayout()
        self.setLayout(grid)

        appList = ['Demo1','Demo2','Demo3']
        for app in appList:
            checkbox = QCheckBox(app)
            checkbox.stateChanged.connect(lambda:self.checkboxState(checkbox))
            grid.addWidget(checkbox)

        self.move(300, 150)
        self.setWindowTitle('Calculator')
        self.show()


if __name__ == '__main__':

    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

My code runs without throwing any errors, but I get an odd result. When I check any checkbox, other than 'Demo3', in the GUI window the console output reads the following:

Demo3 is now deselected

When I select Demo3 in the window the console output alternates between the following:

Demo3 is now selected and Demo3 is now deselected

So, I have the checkbox working correctly for only the last button that is added to the window. If you all can provide me with any pointers, I would be more than grateful.

  • change `checkbox.stateChanged.connect(lambda:self.checkboxState(checkbox))` to `checkbox.stateChanged.connect(lambda state, ch=checkbox : self.checkboxState(ch))` – eyllanesc May 26 '18 at 03:15
  • I tried adding the change you suggested and the application crashed with the following error: **checkbox.stateChanged.connect(lambda state, ch=checkbox : self.checkboxState(ch)) AttributeError: 'Example' object has no attribute 'checkboxState' Abort trap: 6** – Shandon Anderson May 26 '18 at 04:04
  • That error indicates that the error is caused because in your code there is no function checkboxState, you could show your current code, I have only told you to replace that line of code, the rest should stay the same. – eyllanesc May 26 '18 at 04:08
  • In the code I posted I had changed the name of the method checkboxState but in my code I had forgotten to change it. Now that I have your suggested line of code works flawlessly. Yet, I am confused as to why it works exactly. – Shandon Anderson May 26 '18 at 15:00
  • important rule of a programmer: take a reading comprehension course so that you learn to understand the error messages, so you save a lot of time. The errors of very mature libraries are very descriptive. – eyllanesc May 26 '18 at 16:39
  • Also, remember that there is two ways of using functions that can be triggered by many widgets. Either you always feed the function a special parameter that depends on the widget, or you feed no parameter but you check inside the function which widget is `self.sender()`. – Guimoute Jan 27 '20 at 12:25

0 Answers0