PyQt5 QTreeWidget tree structure recursively traverse all current nodes

The
advantages and disadvantages of demos
compared to online methods


Prepare a small demo

Introduction to common small demos
: commodity types and commodity tree nested structure demo
function: click the button to get all currently selected commodities (with a bit of private goods 〃'▽'〃)
Note: space is limited, no child nodes and parents are written The node is selected in linkage, so when you select the child node, please select the parent node yourself, otherwise it will be skipped.

Insert picture description here
Insert picture description here

Code block:
import sys
from PyQt5.QtWidgets import QTreeWidgetItem, QTreeWidget, QWidget, QVBoxLayout, QPushButton, QApplication
from PyQt5.QtCore import Qt


class Demo(QWidget):
    def __init__(self):
        super().__init__()
        # 实例化一个树形结构,隐藏了header
        self.tree = QTreeWidget()
        self.tree.setHeaderHidden(True)
        # 顶级分支
        self.tree_main = QTreeWidgetItem(self.tree)
        self.tree_main.setText(0, '商品种类')
        # 设置一些二级分支
        tree_second = ['电子产品', '水果', '日用品', '喜欢的人']
        self.gen_branch(self.tree_main, tree_second)
        # 设置一些三级分支
        tree_fruit = ['苹果', '香蕉', '梨']
        tree_daily_use = ['纸巾', '毛巾']
        tree_lovers = ['迪迪1号', '迪迪2号']
        # child(1) 意思是分支的第1个节点, 序号从0算起
        self.gen_branch(self.tree_main.child(1), tree_fruit)
        self.gen_branch(self.tree_main.child(2), tree_daily_use)
        self.gen_branch(self.tree_main.child(3), tree_lovers)
        # 一个按钮
        self.pushButton = QPushButton('选好了')
        # 显示出来
        self.qvl = QVBoxLayout()
        self.qvl.addWidget(self.tree)
        self.qvl.addWidget(self.pushButton)
        self.setLayout(self.qvl)

        # 绑定一下槽函数,传入主要的分支节点
        self.pushButton.clicked.connect(lambda: self.get_checked(self.tree_main))

    @staticmethod
    def gen_branch(node: QTreeWidgetItem, texts: list):
        """ 给定某个节点和列表 在该节点生成列表内分支"""
        for text in texts:
            item = QTreeWidgetItem()
            item.setText(0, text)
            item.setCheckState(0, Qt.Unchecked)
            node.addChild(item)

    def get_checked(self, node: QTreeWidgetItem)->list:
        """ 得到当前节点选中的所有分支, 返回一个 list """
        temp_list = []
        # 此处看下方注释 1
        for item in node.takeChildren():
            # 判断是否选中
            if item.checkState(0) == Qt.Checked:
                temp_list.append(item.text(0))
                # 判断是否还有子分支
                if item.childCount():
                    temp_list.extend(self.get_checked(item))
            node.addChild(item)
        print(temp_list)
        return temp_list


if __name__ == '__main__':
    app = QApplication(sys.argv)
    win = Demo()
    win.show()
    sys.exit(app.exec_())

Note 01: In this function, I passed in a node node, the takeChildren() method will take out (delete) all the first-level child branches of the node node , and return a list of all the first-level branches of the node, as follows Shown. This method can only return first-level node information, and use childCount() to determine whether there are child branches, and recursively, until the bottom node. Because when acquired takeChildren () removed all nodes, so at the end of the operation to rejoin the node node
[
<PyQt5.QtWidgets.QTreeWidgetItem object at 0x0000000008464708>, 
<PyQt5.QtWidgets.QTreeWidgetItem object at 0x0000000008464798>, 
]

What are the advantages and disadvantages of this approach?

The biggest advantage is undoubtedly that there is no need to create additional variables to store the information of the child nodes. The information and order of the child nodes are obtained in real time rather than pre-determined. On the downside , I imagine that if this method is used too much, the order of the nodes may change. For example, "apples, bananas" have become "bananas, apples", which has not yet appeared.

Compare online methods

There is a way about QTreeWidgetItemIterator, which is the iterator that comes with Qt, probably as follows

item = QtWidgets.QTreeWidgetItemIterator(self.treeWidget) ,
use item.value() to locate a node, the instance of item.value() is the kind of object in the above list, personal feeling is not too much.


There is also a more violent approach. When generating child nodes, put all child nodes into the scope of the current class, that is, they exist as attributes.
self.item1 = QTreeWidgetItem()

Or it is saved in a list defined in the scope when it is generated. There is a disadvantage to doing so. The node information is predetermined in advance. But the actual situation encountered should be more unknown.
self.item_list = []
self.item_list.append([... ... ])

I'm just a idiot, and your likes will be my biggest motivation for updating.

Guess you like

Origin blog.csdn.net/qq_39177678/article/details/109179729