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

问题描述 投票:0回答:1

类似于Python PyQt - Checkbox to uncheck all other checkboxes

我想有一个复选框

  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()

如何通过此设置获取有效的代码?

python python-3.x pyqt pyqt5 qcheckbox
1个回答
0
投票

您的代码存在各种问题。

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

    要使其正常工作,您应该对创建的所有复选框都具有一定的引用,然后应用所需的状态,同时要非常小心地更改每个复选框的复选框状态。

在下面的示例中,如果未选中所有复选框,或者至少选中了一个,则“全选”和“不选”复选框会被部分选中。

self.checkBoxNone

就是说,让我告诉您,不建议使用复选框来做您正在做的事情,因为从视觉上和从交互的角度来看,这都是违反直觉的。最好使用一个按钮检查所有内容,而另一个按钮则取消选中。另外,在命名变量和属性时要小心。例如,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, wordlist in zip(positions, wordlist): checkB =(QCheckBox(wordlist)) checkB.setStatusTip("Crawling best singals for "+wordlist+"." ) # 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() checkAll非常相似,但是它们引用两个截然不同的对象:一个复选框和一个函数;他们的名字也应该反映出这种差异。虽然不遵循此原则并不代表技术问题,但是当对象(功能,属性等)的数量随程序的增长而增加时,这可能会成为问题:使用清晰明了的名称可提高可读性(和心理参考),即开发

问题跟踪的重要方面。
© www.soinside.com 2019 - 2024. All rights reserved.