Reputation: 487
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.
Upvotes: 1
Views: 270
Reputation: 13691
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_())
Upvotes: 1
Reputation: 120768
You're not using partial
correctly. If both parameters are specified in partial
, then both the arguments of clickBox
will be overwritten with the value of i
. What you need to do is only specify the value of the index
argument, and allow the signal to supply the value of the state
argument. This can be done using a keyword argument, like this:
# checkbox_index = partial(self.clickBox, i, i)
checkbox_index = partial(self.clickBox, index=i)
But note that state
will be a value from the CheckState enum, so if you specifically want to get True/False
, you could use a lambda
instead:
checkbox_index = lambda state, index=i: self.clickBox(state == Qt.Checked, index)
and clickState
would need to look like this:
def clickBox(self, state, index):
print(index)
print(state)
global unfinished_batches, total_batches
if state == True:
unfinished_batches += 1
else:
unfinished_batches -= 1
Upvotes: 1