如何设置 QTreeWidget child 的 child 的 setCheckedState?

How to set the setCheckedState of a QTreeWidget child's child?

我有一个 QTreeWidget,它有一个隐藏的根,2 children 作为 headers,以及 2 children 在 children.

下面
ROOT (HIDDEN)
  |
  |- HEADER 1 (CHILD, NOT CHECKABLE)
  |     |
  |     |- ITEM 11 (CHILD, CHECKABLE)
  |     |- ITEM 12 (CHILD, CHECKABLE)
  |
  |- HEADER 2 (CHILD)
  |     |
  |     | - ITEM 21 (CHILD, CHECKABLE)
  |     | - ITEM 22 (CHILD, CHECKABLE)

使用 item = {} 字典中的变量,我需要 setCheckState of HEADER 1,第 12 项。目前我使用 self.CurrentIndexLabel 跟踪当前选择的标签,虽然这在这个例子中可能是无关紧要的。我已经像这样填充了树:

TreeList = ({
    'Header1': (('Item11', 'Item12', )),
    'Header2': (('Item21', 'Item22', )),
})

item = {'Item12': {'ItemEnabled': 1}}  # 0 = No, 1 = Yes

for key, value in TreeList.items():
    parent = QTreeWidgetItem(self.ListTreeView, [key])
    for val in value:
        child = QTreeWidgetItem([val])
        child.setFlags(child.flags() | Qt.ItemIsUserCheckable)
        child.setCheckState(0, Qt.Unchecked)
        parent.addChild(child)

最初,我需要根据为每个项目添加变量的 item = {} 字典来设置项目是选中还是取消选中,当用户取消选中该项目时,我需要更改 item = {} 字典来反映该项目是否被启用。

我假设我需要使用信号和插槽来检测更改,但我似乎无法弄清楚如何将列表中的项目标记为已选中,而且我不确定如何反映用户选中或取消选中 TreeList.

中的项目

如果我可以使用 1 和 0 跟踪检查或取消检查以更新字典 item = {} 的当前状态,那将是理想的。

完成此任务的最佳方法是什么?我是 python 的新手,所以请多多包涵。我正在使用 Python 3.6 和 PyQt5

QTreeWidgetItem 被选中或未被选中时,会发出 QTreeWidget.itemChanged(item, column) 信号。所以你可以使用它,然后更新插槽中的 item 字典。

正如评论中所说,我认为您使用的 item 字典的结构不合适。使用 QTreeWidgetItem 文本值作为键(或者更好,QTreeWidgetItem 对象本身)会更容易,所以像 item = {'Item12': {'ItemEnabled': True}}

这样的字典

例如:

from PyQt4 import QtCore, QtGui
import sys


class MyApplication(QtGui.QMainWindow):
    def __init__(self):
        super(MyApplication, self).__init__()
        self.item = {'Item12': {'ItemEnabled': True}}
        self.setupUi()

        TreeList = ({
            'Header1': ('Item11', 'Item12',),
            'Header2': ('Item21', 'Item22',),
        })

        for key, value in TreeList.items():
            parent = QtGui.QTreeWidgetItem(self.treeWidget, [key])
            for val in value:
                child = QtGui.QTreeWidgetItem([val])
                child.setFlags(child.flags() | QtCore.Qt.ItemIsUserCheckable)
                child.setCheckState(0, QtCore.Qt.Checked if val in self.item else QtCore.Qt.Unchecked)
                parent.addChild(child)

        self.treeWidget.itemChanged.connect(self.treeWidgetItemChanged)

    def setupUi(self):
        self.centralwidget = QtGui.QWidget(self)
        self.gridLayout = QtGui.QGridLayout(self.centralwidget)
        self.treeWidget = QtGui.QTreeWidget(self.centralwidget)
        self.gridLayout.addWidget(self.treeWidget)
        self.setCentralWidget(self.centralwidget)

    def treeWidgetItemChanged(self, widgetItem, column):
        print("Item {} is checked: {}".format(widgetItem, widgetItem.checkState(column) == QtCore.Qt.Checked))
        itemName = str(widgetItem.text(column))
        try:
            self.item[itemName]['ItemEnabled'] = widgetItem.checkState(column) == QtCore.Qt.Checked
        except KeyError:
            self.item[itemName] = {'ItemEnabled': widgetItem.checkState(column) == QtCore.Qt.Checked}

        print(self.item)


if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    w = MyApplication()
    w.show()
    sys.exit(app.exec_())