Why PYQT5 connecting multiple checkboxes does not work in a loop, but works by writing out everything manually
Question:
I am working on PyQT5 and I have the following list.
self.config_cbs = [self.gui.cb_config_0,
self.gui.cb_config_1,
self.gui.cb_config_2,
self.gui.cb_config_3,
self.gui.cb_config_4,
self.gui.cb_config_5,
self.gui.cb_config_6,
self.gui.cb_config_7,
self.gui.cb_config_8,
self.gui.cb_config_9,
self.gui.cb_config_10,
self.gui.cb_config_11]
I want to connect all checkboxes to the same function.
Does anyone know, why does this NOT work?
for i, cb in enumerate(self.config_cbs):
cb.stateChanged.connect(lambda: self.config_cb_state_changed(i))
But this does work:
self.gui.cb_config_0.stateChanged.connect(lambda: self.config_cb_state_changed(0))
self.gui.cb_config_1.stateChanged.connect(lambda: self.config_cb_state_changed(1))
self.gui.cb_config_2.stateChanged.connect(lambda: self.config_cb_state_changed(2))
...
Aren’t these two equivalent?
Answers:
Solution 1
Can you try with this?
for i, cb in enumerate(self.config_cbs):
cb.stateChanged.connect(lambda i=i: self.config_cb_state_changed(i))
Solution 2
If it still does not work, you can still alter your function config_cb_state_changed()
and identify the checkbox which triggered the signal with self.sender()
(I assume all the code is part of the same class).
...
for cb in self.config_cbs:
cb.stateChanged.connect(self.config_cb_state_changed)
...
def config_cb_state_changed(state: bool):
cb = self.sender()
# If needed, you can find your index i
i = self.config_cbs.index(cb)
# And just to be sure...
assert isinstance(cb, QCheckBox)
assert cb.isChecked() == state
Solution 1 edited
for i, cb in enumerate(self.config_cbs):
cb.stateChanged.connect(lambda state, i=i: self.config_cb_state_changed(i))
I am working on PyQT5 and I have the following list.
self.config_cbs = [self.gui.cb_config_0,
self.gui.cb_config_1,
self.gui.cb_config_2,
self.gui.cb_config_3,
self.gui.cb_config_4,
self.gui.cb_config_5,
self.gui.cb_config_6,
self.gui.cb_config_7,
self.gui.cb_config_8,
self.gui.cb_config_9,
self.gui.cb_config_10,
self.gui.cb_config_11]
I want to connect all checkboxes to the same function.
Does anyone know, why does this NOT work?
for i, cb in enumerate(self.config_cbs):
cb.stateChanged.connect(lambda: self.config_cb_state_changed(i))
But this does work:
self.gui.cb_config_0.stateChanged.connect(lambda: self.config_cb_state_changed(0))
self.gui.cb_config_1.stateChanged.connect(lambda: self.config_cb_state_changed(1))
self.gui.cb_config_2.stateChanged.connect(lambda: self.config_cb_state_changed(2))
...
Aren’t these two equivalent?
Solution 1
Can you try with this?
for i, cb in enumerate(self.config_cbs):
cb.stateChanged.connect(lambda i=i: self.config_cb_state_changed(i))
Solution 2
If it still does not work, you can still alter your function config_cb_state_changed()
and identify the checkbox which triggered the signal with self.sender()
(I assume all the code is part of the same class).
...
for cb in self.config_cbs:
cb.stateChanged.connect(self.config_cb_state_changed)
...
def config_cb_state_changed(state: bool):
cb = self.sender()
# If needed, you can find your index i
i = self.config_cbs.index(cb)
# And just to be sure...
assert isinstance(cb, QCheckBox)
assert cb.isChecked() == state
Solution 1 edited
for i, cb in enumerate(self.config_cbs):
cb.stateChanged.connect(lambda state, i=i: self.config_cb_state_changed(i))