问题
My question is very similar to this post, Python PyQt - Checkbox to uncheck all other checkboxes. However, I am trying to check all other boxes when main checkbox is selected and at the same time, if any of the other boxes are selected independently, then I would like to deselect the main checkbox. I tried modifying the answer provided, but not able to put my head around the 'self.sender' signal. I am not able to change the selection when I deselect a checkbox. Here is the code that I modified using the solution provided by @ eyllanesc.Any help is greatly appreciated, thanks!
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
class Test(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.checkBoxAll = QCheckBox("Select All")
self.checkBoxA = QCheckBox("Select A")
self.checkBoxB = QCheckBox("Select B")
self.checkBoxAll.setChecked(False)
self.checkBoxAll.stateChanged.connect(self.onStateChange)
self.checkBoxA.stateChanged.connect(self.onStateChange)
self.checkBoxB.stateChanged.connect(self.onStateChange)
grid = QGridLayout(self)
grid.addWidget(self.checkBoxAll, 1, 0)
grid.addWidget(self.checkBoxA, 2, 0)
grid.addWidget(self.checkBoxB, 3, 0)
self.setWindowTitle('Test')
self.show()
@pyqtSlot(int)
def onStateChange(self, state):
if state == Qt.Checked:
if self.sender() == self.checkBoxAll:
self.checkBoxA.setChecked(True)
self.checkBoxB.setChecked(True)
elif self.sender() in (self.checkBoxA, self.checkBoxB):
self.checkBoxAll.setChecked(False)
回答1:
With the logic that you have you are creating a loop since the change of state of any element to change the state of another element, the idea is to block the emission of signals when the change of state is implemented in the slot with blockSignals():
from PyQt5 import QtCore, QtGui, QtWidgets
class Test(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.checkBoxAll = QtWidgets.QCheckBox("Select All")
self.checkBoxAll.setChecked(False)
self.checkBoxAll.stateChanged.connect(self.onStateChangePrincipal)
self.checkBoxA = QtWidgets.QCheckBox("Select A")
self.checkBoxB = QtWidgets.QCheckBox("Select B")
self.checkboxes = [self.checkBoxA, self.checkBoxB]
for checkbox in self.checkboxes:
checkbox.stateChanged.connect(self.onStateChange)
grid = QtWidgets.QGridLayout(self)
grid.addWidget(self.checkBoxAll, 1, 0)
grid.addWidget(self.checkBoxA, 2, 0)
grid.addWidget(self.checkBoxB, 3, 0)
self.setWindowTitle('Test')
@QtCore.pyqtSlot(int)
def onStateChangePrincipal(self, state):
if state == QtCore.Qt.Checked:
for checkbox in self.checkboxes:
checkbox.blockSignals(True)
checkbox.setCheckState(state)
checkbox.blockSignals(False)
@QtCore.pyqtSlot(int)
def onStateChange(self, state):
self.checkBoxAll.blockSignals(True)
self.checkBoxAll.setChecked(QtCore.Qt.Unchecked)
self.checkBoxAll.blockSignals(False)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = Test()
w.show()
sys.exit(app.exec_())
来源:https://stackoverflow.com/questions/54014436/qcheckbox-to-check-all-other-qcheckboxes