取消选择并选中PyQt5中的所有复选框



类似于Python PyQt-复选框取消选中所有其他复选框

我想要一个的复选框

  1. 取消选中所有选中的复选框
  2. 以及用于选择所有复选框的复选框
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QMainWindow, QTableView, QGridLayout, QWidget, QCheckBox
from PyQt5.QtGui import QFont
from functools import partial
class MainWindow(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.font = QFont("Helvetica", 9)
self.setFont(self.font)
self.showMaximized()     
grid = QGridLayout()
self.setLayout(grid)
positions = [(i,j) for i in range(5) for j in range(5)]
print('npostions: ', positions)
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']

for position, wordlist in zip(positions, wordlist): 
checkB =(QCheckBox(wordlist)) 
checkB.setStatusTip("Crawling best singals for "+wordlist+"." ) # set Statusbar
checkB.stateChanged.connect(partial(self.checkState, wordlist))
grid.addWidget(checkB, *position)
checkBoxNone = QCheckBox("None Selected")
checkBoxNone.setChecked(True)
checkBoxNone.stateChanged.connect(self.checkState)
grid.addWidget(checkBoxNone, 6, 1)
checkAll = QCheckBox("Select All")
checkAll.setChecked(False)
checkAll.stateChanged.connect(self.selectAll)
grid.addWidget(checkAll, 6, 2)
widget = QWidget()
widget.setLayout(grid) 
self.setCentralWidget(widget)      
self.statusBar().showMessage('Ready')
# Here are the problems. 
# Is it because I have create checkboxes with a for loop?
def selectAll(self, state):
if state == Qt.Checked:
if self.sender() == MainWindow.checkAll:
MainWindow.checkB.setChecked(True)
def checkState(self, checktext, state):
if state == Qt.Checked:
print(checktext)
if self.sender() == MainWindow.checkBoxNone:
MainWindow.checkB.setChecked(False)
elif self.sender() == MainWindow.checkB:
MainWindow.checkBoxNone.setChecked(False)
if __name__ == '__main__':
app = QApplication(sys.argv)
app.setStyle('Fusion')
mw = MainWindow()

如何使用此设置获取工作代码?

您的代码存在各种问题。

  1. 您正在尝试访问class属性,如MainWindow.checkBMainWindow.checkBoxNone等。它们不存在。您应该使用实例属性,使用self.checkB
  2. 为了使上述工作正常进行,您还必须设置这些属性,因此checkBoxNone = QCheckBox("None Selected")应该是self.checkBoxNone = QCheckBox("None Selected"),等等
  3. 您将checkBoxNone.stateChanged连接到一个需要两个位置参数的函数,但stateChanged()只有一个(状态(;没有复选框信号返回文本
  4. 在您的功能中,您没有选中或取消选中任何其他复选框
  5. 即使假设您使用了正确的引用(self.checkBoxNone等(,也不应该像在代码中那样,由于stateChanged信号而选中未选中的框(或相反(,因为这会导致递归
  6. QMainWindow有自己的布局,您不能设置自己的布局;此外,您已经将其设置为中心小部件

要使其发挥作用,您应该对创建的所有复选框进行一些引用,然后应用所需的状态,同时要非常小心地更改每个复选框的复选状态。

在以下示例中,如果不是所有复选框都被选中,或者至少有一个复选框被选中,则"全选"one_answers"不选"复选框显示为部分选中。

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
self.checkBoxes = []
for position,wordin zip(positions, wordlist): 
checkB =(QCheckBox(word)) 
checkB.setStatusTip("Crawling best singals for "+word+"." ) # set Statusbar
checkB.stateChanged.connect(self.checkStates)
grid.addWidget(checkB, *position)
self.checkBoxes.append(checkB)
self.checkBoxNone = QCheckBox("Select none")
self.checkBoxNone.setCheckState(Qt.Unchecked)
self.checkBoxNone.stateChanged.connect(
partial(self.selectBoxes, False))
grid.addWidget(self.checkBoxNone, 6, 1)
self.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()

也就是说,让我告诉你,不建议使用复选框来做你正在做的事情,因为无论是从视觉上还是从交互的角度来看,这都是违反直觉的。最好用一个按钮检查所有内容,用另一个按钮取消检查
此外,在命名变量和属性时要小心;例如,checkAllselectAll非常相似,但它们指的是两个截然不同的对象:一个复选框和一个函数;他们的名字也应该反映出这种差异。虽然不遵循这一原则并不代表技术问题,但当对象(函数、属性等(的数量随着程序的增长而增长时,这可能会成为一个问题:使用清晰描述性的名称可以提高可读性(和心理参考(,这是开发问题跟踪的一个重要方面
循环也有同样的概念:不要对列表和迭代器元素都使用wordlist

相关内容

  • 没有找到相关文章

最新更新