PyQt5 QTreeWidget 树形结构递归遍历当前所有节点的实现
Qt中实现树形结构可以使用QTreeWidget类,也可以使用QTreeView类,本文主要介绍了PyQt5 QTreeWidget 树形结构递归遍历当前所有节点的实现,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
目录
QTreeWidget类中的常用方法
QTreeWidgetItem类中的常用方法
准备一个小demo
这样的做法有什么好处和坏处?
对比网上的方法
QTreeWidget类中的常用方法
方法 | 描述 |
---|---|
setColumnWidth(int column,int width) | 将指定列的宽度设置为给定的值width |
insertTopLevelItems() | 在视图的顶层索引中插入项目列表 |
expandAll() | 展开所有的树形节点 |
invisibleRootItem() | 返回树形控件中不可见的根选项 |
selectedItems() | 返回所有选定的非隐藏项目的列表 |
QTreeWidgetItem类中的常用方法
方法 | 描述 |
---|---|
addChild() | 将子项追加到子列表中 |
setText() | 设置显示的节点文本 |
Text() | 返回显示的节点文本 |
setCheckState(column,state) | 设置指定列的选中状态:Qt.Checked(节点选中),Qt.Unchecked(节点未选中) |
setIcon(column,icon) | 在指定的列中显示图标 |
准备一个小demo
常见小demo
简介:商品种类和商品的树形嵌套结构demo
功能:点击按键获取当前所有被选中的商品(夹带了一点私货〃‘▽'〃)
注意:篇幅有限,没有写子节点和父节点联动选中,所以在选择子节点时麻烦自行将父节点选上,不然会跳过。
代码块儿:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | 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_()) |
注释01:在这个函数中,我传入了一个 node 节点,takeChildren() 这个方法会将该node节点的所有一级子分支拿出来(删除),并返回节点的所有一级分支的列表,如下所示。该方法只能返回一级的节点信息,利用 childCount() 来判断是否有子分支,有则递归,一直到最底部的节点。因为在获取的时候 takeChildren() 删除了所有节点,所以在操作结束后重新加入到 node 节点中
1 2 3 4 | [ <PyQt5.QtWidgets.QTreeWidgetItem object at 0x0000000008464708 >, <PyQt5.QtWidgets.QTreeWidgetItem object at 0x0000000008464798 >, ] |
这样的做法有什么好处和坏处?
最大的好处无疑是不需要创建额外的变量去存储子节点的信息,子节点的信息和顺序都是实时获取的而非前期就定好了的。坏处,我设想这个方法用多了可能会存在节点顺序改变的情况。比如“苹果、香蕉”变成了“香蕉、苹果”,目前未出现。
对比网上的方法
有一个关于 QTreeWidgetItemIterator 的办法,这是Qt中自带的遍历器,大概如下
1 | item = QtWidgets.QTreeWidgetItemIterator( self .treeWidget), |
用 item.value() 来定位到一个节点,item.value() 的实例就是上文列表中的那种对象,个人感觉差不太多。
还有一种比较暴力做法。在生成子节点的时候将所有子节点放到当前类的作用域中,也就是作为属性存在。
1 | self .item1 = QTreeWidgetItem() |
或是生成的时候保存在一个定义在作用域的列表中,这么做有一个坏处,节点的信息都是提前定好了的。但实际上遇到的情况更多应该是未知的。
1 2 | self .item_list = [] self .item_list.append([... ... ])<font face = "Arial, Verdana, sans-serif" ><span style = "white-space: normal;" > < / span>< / font> |
到此这篇关于PyQt5 QTreeWidget 树形结构递归遍历当前所有节点的实现的文章就介绍到这了
原文链接:https://blog.csdn.net/qq_39177678/article/details/109179729