PyQt5 QTreeWidget 樹(shù)形結(jié)構(gòu)遞歸遍歷當(dāng)前所有節(jié)點(diǎn)的實(shí)現(xiàn)
QTreeWidget類(lèi)中的常用方法
| 方法 | 描述 |
|---|---|
| setColumnWidth(int column,int width) | 將指定列的寬度設(shè)置為給定的值width |
| insertTopLevelItems() | 在視圖的頂層索引中插入項(xiàng)目列表 |
| expandAll() | 展開(kāi)所有的樹(shù)形節(jié)點(diǎn) |
| invisibleRootItem() | 返回樹(shù)形控件中不可見(jiàn)的根選項(xiàng) |
| selectedItems() | 返回所有選定的非隱藏項(xiàng)目的列表 |
QTreeWidgetItem類(lèi)中的常用方法
| 方法 | 描述 |
|---|---|
| addChild() | 將子項(xiàng)追加到子列表中 |
| setText() | 設(shè)置顯示的節(jié)點(diǎn)文本 |
| Text() | 返回顯示的節(jié)點(diǎn)文本 |
| setCheckState(column,state) | 設(shè)置指定列的選中狀態(tài):Qt.Checked(節(jié)點(diǎn)選中),Qt.Unchecked(節(jié)點(diǎn)未選中) |
| setIcon(column,icon) | 在指定的列中顯示圖標(biāo) |
準(zhǔn)備一個(gè)小demo
常見(jiàn)小demo
簡(jiǎn)介:商品種類(lèi)和商品的樹(shù)形嵌套結(jié)構(gòu)demo
功能:點(diǎn)擊按鍵獲取當(dāng)前所有被選中的商品(夾帶了一點(diǎn)私貨〃‘▽'〃)
注意:篇幅有限,沒(méi)有寫(xiě)子節(jié)點(diǎn)和父節(jié)點(diǎn)聯(lián)動(dòng)選中,所以在選擇子節(jié)點(diǎn)時(shí)麻煩自行將父節(jié)點(diǎn)選上,不然會(huì)跳過(guò)。


代碼塊兒:
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__()
# 實(shí)例化一個(gè)樹(shù)形結(jié)構(gòu),隱藏了header
self.tree = QTreeWidget()
self.tree.setHeaderHidden(True)
# 頂級(jí)分支
self.tree_main = QTreeWidgetItem(self.tree)
self.tree_main.setText(0, '商品種類(lèi)')
# 設(shè)置一些二級(jí)分支
tree_second = ['電子產(chǎn)品', '水果', '日用品', '喜歡的人']
self.gen_branch(self.tree_main, tree_second)
# 設(shè)置一些三級(jí)分支
tree_fruit = ['蘋(píng)果', '香蕉', '梨']
tree_daily_use = ['紙巾', '毛巾']
tree_lovers = ['迪迪1號(hào)', '迪迪2號(hào)']
# child(1) 意思是分支的第1個(gè)節(jié)點(diǎn), 序號(hào)從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)
# 一個(gè)按鈕
self.pushButton = QPushButton('選好了')
# 顯示出來(lái)
self.qvl = QVBoxLayout()
self.qvl.addWidget(self.tree)
self.qvl.addWidget(self.pushButton)
self.setLayout(self.qvl)
# 綁定一下槽函數(shù),傳入主要的分支節(jié)點(diǎn)
self.pushButton.clicked.connect(lambda: self.get_checked(self.tree_main))
@staticmethod
def gen_branch(node: QTreeWidgetItem, texts: list):
""" 給定某個(gè)節(jié)點(diǎn)和列表 在該節(jié)點(diǎn)生成列表內(nèi)分支"""
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:
""" 得到當(dāng)前節(jié)點(diǎn)選中的所有分支, 返回一個(gè) 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:在這個(gè)函數(shù)中,我傳入了一個(gè) node 節(jié)點(diǎn),takeChildren() 這個(gè)方法會(huì)將該node節(jié)點(diǎn)的所有一級(jí)子分支拿出來(lái)(刪除),并返回節(jié)點(diǎn)的所有一級(jí)分支的列表,如下所示。該方法只能返回一級(jí)的節(jié)點(diǎn)信息,利用 childCount() 來(lái)判斷是否有子分支,有則遞歸,一直到最底部的節(jié)點(diǎn)。因?yàn)樵讷@取的時(shí)候 takeChildren() 刪除了所有節(jié)點(diǎn),所以在操作結(jié)束后重新加入到 node 節(jié)點(diǎn)中
[ <PyQt5.QtWidgets.QTreeWidgetItem object at 0x0000000008464708>, <PyQt5.QtWidgets.QTreeWidgetItem object at 0x0000000008464798>, ]
這樣的做法有什么好處和壞處?
最大的好處無(wú)疑是不需要?jiǎng)?chuàng)建額外的變量去存儲(chǔ)子節(jié)點(diǎn)的信息,子節(jié)點(diǎn)的信息和順序都是實(shí)時(shí)獲取的而非前期就定好了的。壞處,我設(shè)想這個(gè)方法用多了可能會(huì)存在節(jié)點(diǎn)順序改變的情況。比如“蘋(píng)果、香蕉”變成了“香蕉、蘋(píng)果”,目前未出現(xiàn)。
對(duì)比網(wǎng)上的方法
有一個(gè)關(guān)于 QTreeWidgetItemIterator 的辦法,這是Qt中自帶的遍歷器,大概如下
item = QtWidgets.QTreeWidgetItemIterator(self.treeWidget),
用 item.value() 來(lái)定位到一個(gè)節(jié)點(diǎn),item.value() 的實(shí)例就是上文列表中的那種對(duì)象,個(gè)人感覺(jué)差不太多。
還有一種比較暴力做法。在生成子節(jié)點(diǎn)的時(shí)候?qū)⑺凶庸?jié)點(diǎn)放到當(dāng)前類(lèi)的作用域中,也就是作為屬性存在。
self.item1 = QTreeWidgetItem()
或是生成的時(shí)候保存在一個(gè)定義在作用域的列表中,這么做有一個(gè)壞處,節(jié)點(diǎn)的信息都是提前定好了的。但實(shí)際上遇到的情況更多應(yīng)該是未知的。
self.item_list = []
self.item_list.append([... ... ])
到此這篇關(guān)于PyQt5 QTreeWidget 樹(shù)形結(jié)構(gòu)遞歸遍歷當(dāng)前所有節(jié)點(diǎn)的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)PyQt5 QTreeWidget 樹(shù)形結(jié)構(gòu)遍歷內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python3+PyQt5 自定義窗口部件--使用窗口部件樣式表的方法
今天小編就為大家分享一篇python3+PyQt5 自定義窗口部件--使用窗口部件樣式表的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-06-06
解決springboot yml配置 logging.level 報(bào)錯(cuò)問(wèn)題
今天小編就為大家分享一篇解決springboot yml配置 logging.level 報(bào)錯(cuò)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-02-02
Django框架實(shí)現(xiàn)的簡(jiǎn)單分頁(yè)功能示例
這篇文章主要介紹了Django框架實(shí)現(xiàn)的簡(jiǎn)單分頁(yè)功能,在之前一篇留言板之上增加了簡(jiǎn)單分頁(yè)功能,涉及Paginator模塊的簡(jiǎn)單使用技巧,需要的朋友可以參考下2018-12-12
python中pytest收集用例規(guī)則與運(yùn)行指定用例詳解
這篇文章主要介紹了python中pytest收集用例規(guī)則與運(yùn)行指定用例詳解,天會(huì)講解一下pytest是如何收集我們寫(xiě)好的用例?我們又有哪些方式來(lái)運(yùn)行單個(gè)用例或者批量運(yùn)行用例呢,需要的朋友可以參考下2019-06-06
python類(lèi)繼承與子類(lèi)實(shí)例初始化用法分析
這篇文章主要介紹了python類(lèi)繼承與子類(lèi)實(shí)例初始化用法,實(shí)例分析了Python類(lèi)的使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-04-04
python twilio模塊實(shí)現(xiàn)發(fā)送手機(jī)短信功能
這篇文章主要介紹了python twilio模塊實(shí)現(xiàn)發(fā)送手機(jī)短信的功能,本文圖文并茂給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-08-08
pytest進(jìn)階教程之fixture函數(shù)詳解
這篇文章主要給大家介紹了關(guān)于pytest進(jìn)階教程之fixture函數(shù)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03
python讀取txt文件并取其某一列數(shù)據(jù)的示例
今天小編就為大家分享一篇python讀取txt文件并取其某一列數(shù)據(jù)的示例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-02-02

