我如何以编程方式 expand/collapse 和 select 树中的项目?

How can I programmatically expand/collapse and select an item in a tree?

假设我在 Qt Designer 中添加了一个名为 treeView 的 TreeView 小部件,我正在使用此代码向其中添加一些项目:

class StandardItem(Qt.QStandardItem):
    def __init__(self, txt='', font_size=11, set_bold=False, color=Qt.QColor(0, 0, 0)):
        super().__init__()
        fnt = Qt.QFont('Open Sans', font_size)
        fnt.setBold(set_bold)
        self.setEditable(False)
        self.setForeground(color)
        self.setFont(fnt)
        self.setText(txt)


model = Qt.QStandardItemModel()
rootNode = model.invisibleRootItem()
A = StandardItem("A")
A.appendRows([StandardItem("1"),StandardItem("2"),StandardItem("3")])
B = StandardItem("B")
B.appendRows([StandardItem("1"),StandardItem("2")])
rootNode.appendRows([A,B])
self.treeView.setModel(model)

如何编写 collapses/expands 项 A 的函数?我如何编写一个函数来选择项目 A,就好像它已被单击一样?我可能在文档中遗漏了一些东西。

扩展和选择是影响视觉部分的任务,因此必须通过视觉来处理。第一个任务是通过与视图关联的 setExpanded() method and the second using the select() method of the selectionModel() 完成的,在这两种情况下都使用与项目关联的 QModelIndex:

import sys
from PyQt5 import Qt


class StandardItem(Qt.QStandardItem):
    def __init__(self, txt="", font_size=11, set_bold=False, color=Qt.QColor(0, 0, 0)):
        super().__init__()
        fnt = Qt.QFont("Open Sans", font_size)
        fnt.setBold(set_bold)
        self.setEditable(False)
        self.setForeground(color)
        self.setFont(fnt)
        self.setText(txt)


class MainWindow(Qt.QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.treeView = Qt.QTreeView()
        self.setCentralWidget(self.treeView)

        self.model = Qt.QStandardItemModel()
        rootNode = self.model.invisibleRootItem()
        A = StandardItem("A")
        A.appendRows([StandardItem("1"), StandardItem("2"), StandardItem("3")])
        B = StandardItem("B")
        B.appendRows([StandardItem("1"), StandardItem("2")])
        rootNode.appendRows([A, B])

        self.treeView.setModel(self.model)

        index_A = A.index()

        self.treeView.setExpanded(index_A, True)
        self.treeView.selectionModel().select(index_A, Qt.QItemSelectionModel.Select)


def main():
    app = Qt.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    app.exec_()


if __name__ == "__main__":
    main()

注:

似乎 QStandardItem 的 index() 函数有一个错误,因为它有时 returns 无效的 QModelIndex 对于有效的 QStandardItem。

print(A.child(0).index().isValid())

输出:

False

这是因为当添加子项时,“A”不是模型的一部分,然后模型在这些子项中为空,正如可以看到的那样。

print(A.child(0).model())

输出:

None

如果先将“A”添加到模型,然后再添加子项,则模型通过。

self.model = Qt.QStandardItemModel()
rootNode = self.model.invisibleRootItem()
A = StandardItem("A")
B = StandardItem("B")
rootNode.appendRows([A, B])

A.appendRows([StandardItem("1"), StandardItem("2"), StandardItem("3")])
B.appendRows([StandardItem("1"), StandardItem("2")])

print(A.child(0).model())
print(A.child(0).index().isValid())

输出:

<PyQt5.QtGui.QStandardItemModel object at 0x7fb40aa868b0>
True

在那种情况下,最好使用 QStandardItemModel 的 indexFromItem() 方法:

self.treeView.selectionModel().select(
    self.model.indexFromItem(A.child(0)), Qt.QItemSelectionModel.Select
)