PyQt树小部件,添加动态删除复选框

sud*_*ang 4 python checkbox pyqt qtreewidgetitem qtreeview

我正在尝试创建一个树窗口小部件,它基本上允许用户查看各种数据细分,并可以选择删除某些项目.为了做到这一点,我希望有与每个顶级项目和每个子项相关联的复选框,以便用户可以选择要删除的顶级项目(以及该顶级项目的所有子项).或者删除哪些特定的孩子.为了让您更好地了解我创建了一个示例,其中[x]表示选中的复选框,[]表示一个空复选框:

>Beverages Allowed in Stadium [ ]
    Soda                      [ ]
    Water                     [ ]
    Tea                       [ ]
    Spirits                   [X]
    Ale                       [ ]

>Tickets                      [X]
    Row A                     [X]
    Row B                     [X]
    Row C                     [X]
    Lawn                      [X]
Run Code Online (Sandbox Code Playgroud)

有什么建议如何实现?我不知道它是否有困难,但我为复选框分配了一个单独的列.

And*_*ndy 16

除了您提供的答案之外,您还可以通过使用ItemIsTristate父元素上的标志来简化逻辑.

from PyQt4.QtCore import * 
from PyQt4.QtGui import * 
import sys

def main(): 
    app     = QApplication (sys.argv)
    tree    = QTreeWidget ()
    headerItem  = QTreeWidgetItem()
    item    = QTreeWidgetItem()

    for i in xrange(3):
        parent = QTreeWidgetItem(tree)
        parent.setText(0, "Parent {}".format(i))
        parent.setFlags(parent.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable)
        for x in xrange(5):
            child = QTreeWidgetItem(parent)
            child.setFlags(child.flags() | Qt.ItemIsUserCheckable)
            child.setText(0, "Child {}".format(x))
            child.setCheckState(0, Qt.Unchecked)
    tree.show() 
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()
Run Code Online (Sandbox Code Playgroud)

三个最重要的代码行是:

parent.setFlags(parent.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable)
Run Code Online (Sandbox Code Playgroud)

这个将父元素设置为三态复选框.

child.setFlags(child.flags() | Qt.ItemIsUserCheckable)
child.setCheckState(0, Qt.Unchecked)
Run Code Online (Sandbox Code Playgroud)

这些将子项设置为可选,并将默认设置为未选中.如果孩子的复选框没有给出状态,则不会出现复选框元素.


上面的代码构建了一个非常简单的树.

简单的树

但是,如果我选中父元素上的复选框,则会自动选择所有子项:

父选择

如果,我希望取消选择一个孩子,则父母进入部分选中(三态):

三态

如果未选择所有子项,则自动取消选择父项.如果未选择父级,则也会自动取消选择所有子级.


pkl*_*aus 8

我将 @andy 的很棒的示例移植到 PyQt5:

from PyQt5 import QtWidgets
from PyQt5 import QtCore
from PyQt5 import QtGui
from PyQt5.Qt import Qt
import sys

def main(): 
    app     = QtWidgets.QApplication(sys.argv)
    tree    = QtWidgets.QTreeWidget()
    headerItem  = QtWidgets.QTreeWidgetItem()
    item    = QtWidgets.QTreeWidgetItem()

    for i in range(3):
        parent = QtWidgets.QTreeWidgetItem(tree)
        parent.setText(0, "Parent {}".format(i))
        parent.setFlags(parent.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable)
        for x in range(5):
            child = QtWidgets.QTreeWidgetItem(parent)
            child.setFlags(child.flags() | Qt.ItemIsUserCheckable)
            child.setText(0, "Child {}".format(x))
            child.setCheckState(0, Qt.Unchecked)
    tree.show() 
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()
Run Code Online (Sandbox Code Playgroud)

截屏