Michele Rava
Michele Rava

Reputation: 304

Python - PyQt5 how to treat GUI's checkboxes as separated object?

I'm pretty new in studying Qt and in the case Qt for Python; I've a trouble about the PyQt5 checkbox object. In the following code, as I check a checkbox, I get a signal redirected to the connected function. It rightly shows up if the box has been checked or uncheked, however it seems my script makes confusion among which box has got changed state. For example if I check the first one, then all the checks i perform, after the first one, show the name value bound to the earliest object, like if they all were actually the same object or they have the same address. Instead if I check and uncheck a box, then the next checked one returns the right name bound to that specific checkbox in output. What am I doing wrong?

Here's the class code:

class window_gui(QMainWindow):
def __init__(self):
    QtWidgets.QMainWindow.__init__(self)
    mainWindow = loadUi("utilities/mygui_gui.ui", self)
    self.setWindowTitle("window name")
    #checkBox per selezione uno: sensore sul checked yes or not
    mainWindow.checkOne.clicked.connect(self.selectBooks)
    # checkBox per selezione due: sensore sul checked yes or not
    mainWindow.checkTwo.toggled.connect(self.selectBooks)
    # checkBox per selezione tre: sensore sul checked yes or not
    mainWindow.checkThree.toggled.connect(self.selectBooks)
    # checkBox per selezione quattro: sensore sul checked yes or not
    mainWindow.checkFour.toggled.connect(self.selectBooks)
    # checkBox per selezione cinque: sensore sul checked yes or not
    mainWindow.checkFive.toggled.connect(self.selectBooks)

def selectBooks(self, toggle):
    if toggle == QtCore.Qt.Checked:
        if self.checkOne.isChecked():
            print(self.checkOne.text(), "1")
        elif self.checkTwo.isChecked():
            print(self.checkTwo.text(), "2")
        elif self.checkThree.isChecked():
            print(self.checkThree.text(), "3")
        elif self.checkFour.isChecked():
            print(self.checkFour.text(), "4")
        elif self.checkFive.isChecked():
            print(self.checkFive.text(), "5")
        else:
            print("error")
        print('Checked')
    else:
        print('Unchecked')

Upvotes: 0

Views: 586

Answers (1)

Jonas
Jonas

Reputation: 1847

When checkOne is checked and you click checkTwo, you enter selectBooks. In that function you enter the if-else-statement and the first condition is self.checkOne.isChecked(), which is still True, so you print(self.checkOne.text(), "1"), although you just clicked checkTwo.

You could make a slot for each QCheckBox (option 1), otherwise you need to tell your slot somehow which QCheckbox was just clicked (see option 2).

Also you have to use the stateChanged signal.

option 1

from PyQt5 import QtWidgets, QtCore, QtGui
import sys

class window_gui(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.checkOne = QtWidgets.QCheckBox('one')
        self.checkTwo = QtWidgets.QCheckBox('two')
        self.vlayout = QtWidgets.QVBoxLayout()
        self.vlayout.addWidget(self.checkOne)
        self.vlayout.addWidget(self.checkTwo)
        self.setLayout(self.vlayout)
        self.checkOne.stateChanged.connect(self.selectBooks1)
        self.checkTwo.stateChanged.connect(self.selectBooks2)

    def selectBooks1(self, toggle):
        if toggle == QtCore.Qt.Checked:
            print('checked 1')
        else:
            print('unchecked 1')

    def selectBooks2(self, toggle):
        if toggle == QtCore.Qt.Checked:
            print('checked 2')
        else:
            print('unchecked 2')

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    w = window_gui()
    w.show()
    app.exec()

option 2 (check out 'lambda' expressions):

from PyQt5 import QtWidgets, QtCore, QtGui
import sys

class window_gui(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.checkOne = QtWidgets.QCheckBox('one')
        self.checkTwo = QtWidgets.QCheckBox('two')
        self.vlayout = QtWidgets.QVBoxLayout()
        self.vlayout.addWidget(self.checkOne)
        self.vlayout.addWidget(self.checkTwo)
        self.setLayout(self.vlayout)
        self.checkOne.stateChanged.connect(lambda state=self.checkOne.isChecked(), no=1: self.selectBooks(state, no))
        self.checkTwo.stateChanged.connect(lambda state=self.checkTwo.isChecked(), no=2: self.selectBooks(state, no))

    def selectBooks(self, toggle, no):
        if toggle == QtCore.Qt.Checked:
            print('checked '+str(no))
        else:
            print('unchecked '+str(no))

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    w = window_gui()
    w.show()
    app.exec()

Upvotes: 1

Related Questions