Search code examples
pythonpyqt5signals-slotsqcheckbox

Send state of a QCheckBox and a number when clicked


I'm trying to pass two separate variables via a QCheckBox clicked signal: its post-pressed state, and its index in the list.

For example, this is my code:

# pip install pyqt5
from PyQt5.QtMultimediaWidgets import *
from PyQt5.QtMultimedia import *
from functools import partial
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5 import *
import sys
batch_name = ['Test1', 'test2', 'test']
total_batches = 0
unfinished_batches = 0
class MainMenu(QWidget):
    def __init__(self, parent = None):
        global total_batches, unfinished_batches, batch_name
        super(MainMenu, self).__init__(parent)
        self.scroll = QScrollArea(self)
        self.scroll.setWidgetResizable(True)
        self.content = QWidget()
        self.scroll.setWidget(self.content)
        self.lay = QGridLayout(self.content)
        for i, j in enumerate(batch_name):
            self.btnName = QPushButton(j, self)
            self.btnName.setFlat(True)
            self.lay.addWidget(self.btnName, i, 1)
            self.check_box = QCheckBox(self)
            checkbox_index = partial(self.clickBox, i, i)
            self.check_box.stateChanged.connect(checkbox_index)
            self.lay.addWidget(self.check_box, i, 0)
            total_batches += 1
    def clickBox(self, state, index):
        print(index)
        print(state)
        global unfinished_batches, total_batches
        if state == Qt.Checked:
            unfinished_batches += 1
        else:
            unfinished_batches -= 1


if __name__ == '__main__':
    app = QApplication(sys.argv)
    main = MainMenu()
    main.show()
    sys.exit(app.exec_())

(Yes, I know I'm passing the index threw twice.)

So lets say, I press the first QCheckBox (Test1): I should get True for the state, and 0 for the index. If I press Test1 again, I expect to get False for the state, and again 0 for the index. For just one more example, if I press test (last QCheckBox) I should expect to get True for the state, and 2 for the index, and pressing it again, I should get False for the state, and again, 2 for the index.

The code above gives me the index, but it doesn't give me its state - that's what I'm stuck on. What I am expecting to happen if the QCheckBox is pressed then I should get True where I don't.


Solution

  • Try it:

    import sys
    from functools import partial
    from PyQt5.QtWidgets import *
    from PyQt5.QtCore import *
    from PyQt5.QtGui import *
    
    
    class MainMenu(QWidget):
        def __init__(self, parent = None):
            super(MainMenu, self).__init__(parent)
    
            batch_name = ['Test1', 'test2', 'test']
            lay = QGridLayout(self)
    
            for i, j in enumerate(batch_name):
                check_box = QCheckBox()
                lay.addWidget(check_box, i, 0)
    
                btnName = QPushButton(j)
                btnName.setFlat(True)
                btnName.setCheckable(True)
                btnName.clicked.connect(partial(self.btnCliced, i, j, check_box))
                lay.addWidget(btnName, i, 1)
    
                check_box.stateChanged.connect(partial(self.clickBox, i, j, btnName))            
    
        def clickBox(self, i, j, btnName, state):             
            print(f'clickBox:  i={i}, j={j}, state={state} : {bool(state)};')
            if state: btnName.setChecked(True)
            else: btnName.setChecked(False)
    
        def btnCliced(self, i, j, check_box, state):             
            print(f'btnCliced: i={i}, j={j}, state={state};')
            if state: check_box.setChecked(True)
            else: check_box.setChecked(False)
    
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        main = MainMenu()
        main.show()
        sys.exit(app.exec_())
    

    enter image description here