Существуют различные проблемы с вашим кодом.
- вы пытаетесь получить доступ к class атрибутам, таким как
MainWindow.checkB
, MainWindow.checkBoxNone
, et c. Их не существует. Вы должны использовать атрибуты instance , используя такие вещи, как self.checkB
; - , чтобы вышеупомянутая работа, вы также должны установить эти атрибуты, поэтому
checkBoxNone = QCheckBox("None Selected")
должен be self.checkBoxNone = QCheckBox("None Selected")
, et c. - вы подключаете
checkBoxNone.stateChanged
к функции, которая требует двух позиционных аргументов, но stateChanged()
имеет только один (состояние) ; Сигнал no checkbox не возвращает текст; - в ваших функциях вы не проверяете и не снимаете какие-либо другие флажки;
- даже при условии, что вы использовали правильные ссылки (
self.checkBoxNone
, et c), вы никогда не должны ставить галочку (или наоборот) в результате сигнала stateChanged, как вы это сделали в своем коде, потому что это приведет к рекурсии; - QMainWindow имеет свою собственную разметку, Вы не можете установить свои собственные; Кроме того, вы уже собираетесь установить его для центрального виджета;
Для того, чтобы он работал, вы должны иметь некоторую ссылку на все созданные вами флажки, а затем применить желаемое состояние, оставаясь при этом очень внимательно относитесь к изменению состояния проверки каждого блока.
В следующем примере флажки «выбрать все» и «выбрать нет» отображаются частично отмеченными, если, соответственно, установлены не все флажки или хотя бы один .
class MainWindow(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
grid = QGridLayout()
# You *cannot* set a layout to a main window
# self.setLayout(grid)
positions = [(i,j) for i in range(5) for j in range(5)]
wordlist = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y']
# use a list to keep a reference to all checkboxes
<b>self.checkBoxes = []</b>
for position, <b>word</b> in zip(positions, wordlist):
checkB =(QCheckBox(word))
checkB.setStatusTip("Crawling best singals for "+<b>word</b>+"." ) # set Statusbar
checkB.stateChanged.connect(self.checkStates)
grid.addWidget(checkB, *position)
<b>self.checkBoxes.append(checkB)</b>
<b>self.</b>checkBoxNone = QCheckBox("Select none")
self.checkBoxNone.setCheckState(Qt.Unchecked)
self.checkBoxNone.stateChanged.connect(
partial(self.selectBoxes, False))
grid.addWidget(self.checkBoxNone, 6, 1)
<b>self.</b>checkBoxAll = QCheckBox("Select All")
self.checkBoxAll.setCheckState(Qt.PartiallyChecked)
self.checkBoxAll.stateChanged.connect(
partial(self.selectBoxes, True))
grid.addWidget(self.checkBoxAll, 6, 2)
widget = QWidget()
widget.setLayout(grid)
self.setCentralWidget(widget)
self.statusBar().showMessage('Ready')
def checkStates(self):
states = [c.isChecked() for c in self.checkBoxes]
# temporarily block signals so that there is no recursive calls
self.checkBoxAll.blockSignals(True)
self.checkBoxNone.blockSignals(True)
# set the "select all" fully checked too if all boxes are checked,
# otherwise make it partially checked
self.checkBoxAll.setCheckState(
Qt.Checked if all(states) else Qt.PartiallyChecked)
# set the "select none" unchecked only if all boxes are unchecked,
# otherwise make it partially checked
self.checkBoxNone.setCheckState(
Qt.Unchecked if not any(states) else Qt.PartiallyChecked)
# unblock signals back
self.checkBoxAll.blockSignals(False)
self.checkBoxNone.blockSignals(False)
def selectBoxes(self, state):
for check in self.checkBoxes:
check.blockSignals(True)
check.setChecked(state)
check.blockSignals(False)
self.checkStates()
Тем не менее, позвольте мне сказать вам, что использование флажка для того, чтобы делать то, что вы делаете, не рекомендуется, так как это нелогично, как визуально, так и с точки зрения взаимодействия. Лучше использовать кнопку для проверки всего, а другую для снятия отметки.
Также будьте осторожны при именовании переменных и атрибутов; например, checkAll
и selectAll
очень похожи, но они ссылаются на два разных и очень разных объекта: флажок и функцию; их имена также должны отражать эту разницу. Хотя несоблюдение этого принципа не представляет технической проблемы, оно может стать проблемой, когда число объектов (функций, атрибутов и т. Д. c) растет вместе с вашей программой: использование понятных и описательных имен улучшает читабельность (и умственную ссылку) , что является важным аспектом как для разработки , так и отслеживания проблем.
Та же концепция применима к циклам: не используйте wordlist
для списка и элемента итератора.