Tree Widget -- 基本方法
阅读原文时间:2023年07月11日阅读:1

Tree Widget这个空间类似于一种表格的形式,是一种树状结构

效果图:

第一步:打开designer.exe,拖动一个Tree Widget空间到主窗口上

第二步:双击Tree Widget,添加节点以及子节点

最后添加完后的图形为

可以看到目前还没有什么效果,点击"Properties"我们给它换一下字体颜色和背景色。

首先选中Test1

下滑右边的属性,找到"backgroud",设置Style为Solid,设置Color为想要的,点击右侧那三个点。可以看到颜色已经改变了,想要改变Value那一列某一行的颜色,选中Test1右侧的waiting,对背景色进行设置。另外,下面的foreground,是对字体颜色进行设置,设置方法差不多。

那么最后运行出来的效果就是:

自己手动一项一项添加是不是很麻烦,用代码进行添加或许会容易许多,我们先来看看它UI转换成代码之后的py文件。

treeview3.py

# -*- coding: utf-8 -*-

Form implementation generated from reading ui file 'treeview3.ui'

Created by: PyQt5 UI code generator 5.13.0

WARNING! All changes made in this file will be lost!

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(800, 600)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.treeWidget = QtWidgets.QTreeWidget(self.centralwidget)
self.treeWidget.setGeometry(QtCore.QRect(200, 120, 256, 192))
self.treeWidget.setObjectName("treeWidget")
font = QtGui.QFont()
font.setPointSize(14)
self.treeWidget.headerItem().setFont(0, font)
font = QtGui.QFont()
font.setPointSize(14)
self.treeWidget.headerItem().setFont(1, font)
item_0 = QtWidgets.QTreeWidgetItem(self.treeWidget)
brush = QtGui.QBrush(QtGui.QColor(170, 0, 255))
brush.setStyle(QtCore.Qt.SolidPattern)
item_0.setBackground(0, brush)
brush = QtGui.QBrush(QtGui.QColor(0, 255, 0))
brush.setStyle(QtCore.Qt.SolidPattern)
item_0.setBackground(1, brush)
item_1 = QtWidgets.QTreeWidgetItem(item_0)
item_1 = QtWidgets.QTreeWidgetItem(item_0)
item_1 = QtWidgets.QTreeWidgetItem(item_0)
item_1 = QtWidgets.QTreeWidgetItem(item_0)
item_0 = QtWidgets.QTreeWidgetItem(self.treeWidget)
item_1 = QtWidgets.QTreeWidgetItem(item_0)
item_1 = QtWidgets.QTreeWidgetItem(item_0)
item_1 = QtWidgets.QTreeWidgetItem(item_0)
item_1 = QtWidgets.QTreeWidgetItem(item_0)
item_1 = QtWidgets.QTreeWidgetItem(item_0)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)

    self.retranslateUi(MainWindow)  
    QtCore.QMetaObject.connectSlotsByName(MainWindow)

def retranslateUi(self, MainWindow):  
    \_translate = QtCore.QCoreApplication.translate  
    MainWindow.setWindowTitle(\_translate("MainWindow", "MainWindow"))  
    self.treeWidget.headerItem().setText(0, \_translate("MainWindow", "Key"))  
    self.treeWidget.headerItem().setText(1, \_translate("MainWindow", "Value"))  
    \_\_sortingEnabled = self.treeWidget.isSortingEnabled()  
    self.treeWidget.setSortingEnabled(False)  
    self.treeWidget.topLevelItem(0).setText(0, \_translate("MainWindow", "Test1"))  
    self.treeWidget.topLevelItem(0).setText(1, \_translate("MainWindow", "waiting"))  
    self.treeWidget.topLevelItem(0).child(0).setText(0, \_translate("MainWindow", "a"))  
    self.treeWidget.topLevelItem(0).child(0).setText(1, \_translate("MainWindow", "waiting"))  
    self.treeWidget.topLevelItem(0).child(1).setText(0, \_translate("MainWindow", "b"))  
    self.treeWidget.topLevelItem(0).child(1).setText(1, \_translate("MainWindow", "waiting"))  
    self.treeWidget.topLevelItem(0).child(2).setText(0, \_translate("MainWindow", "c"))  
    self.treeWidget.topLevelItem(0).child(2).setText(1, \_translate("MainWindow", "waiting"))  
    self.treeWidget.topLevelItem(0).child(3).setText(0, \_translate("MainWindow", "d"))  
    self.treeWidget.topLevelItem(0).child(3).setText(1, \_translate("MainWindow", "waiting"))  
    self.treeWidget.topLevelItem(1).setText(0, \_translate("MainWindow", "Test2"))  
    self.treeWidget.topLevelItem(1).setText(1, \_translate("MainWindow", "waiting"))  
    self.treeWidget.topLevelItem(1).child(0).setText(0, \_translate("MainWindow", "a"))  
    self.treeWidget.topLevelItem(1).child(0).setText(1, \_translate("MainWindow", "waiting"))  
    self.treeWidget.topLevelItem(1).child(1).setText(0, \_translate("MainWindow", "b"))  
    self.treeWidget.topLevelItem(1).child(1).setText(1, \_translate("MainWindow", "waiting"))  
    self.treeWidget.topLevelItem(1).child(2).setText(0, \_translate("MainWindow", "c"))  
    self.treeWidget.topLevelItem(1).child(2).setText(1, \_translate("MainWindow", "waiting"))  
    self.treeWidget.topLevelItem(1).child(3).setText(0, \_translate("MainWindow", "d"))  
    self.treeWidget.topLevelItem(1).child(3).setText(1, \_translate("MainWindow", "waiting"))  
    self.treeWidget.topLevelItem(1).child(4).setText(0, \_translate("MainWindow", "e"))  
    self.treeWidget.topLevelItem(1).child(4).setText(1, \_translate("MainWindow", "waiting"))  
    self.treeWidget.setSortingEnabled(\_\_sortingEnabled)

动态添加数据

很多,不详看,那么我们只需要注意其中几条语句就可以。

第一个,设置颜色的语句块

1 item_0 = QtWidgets.QTreeWidgetItem(self.treeWidget)
2 brush = QtGui.QBrush(QtGui.QColor(170, 0, 255))
3 brush.setStyle(QtCore.Qt.SolidPattern)
4 item_0.setBackground(0, brush)

其中item_0就是根节点

第二个,创建子节点的语句

item_1 = QtWidgets.QTreeWidgetItem(item_0)

第三个,设置每个节点的文本

1 self.treeWidget.topLevelItem(0).setText(0, _translate("MainWindow", "Test1"))
2 self.treeWidget.topLevelItem(0).setText(1, _translate("MainWindow", "waiting"))

topLevelItem(0)里面的0代表第一个根节点,setText(0, ….)里面的0代表第一列,1代表第二列。

1 self.treeWidget.topLevelItem(0).child(0).setText(0, _translate("MainWindow", "a"))
2 self.treeWidget.topLevelItem(0).child(0).setText(1, _translate("MainWindow", "waiting"))

child(0)里面的0代表第一个子节点

用界面添加的属于静态添加数据,并且一条一条的插入,修改样式很浪费时间,而且代码看起来也会比较多,如果动态插入的话会快许多。所以,想了一个办法,将要填入树结构的数据存放在一个类里面,类名为DataCollection。

treeview_data.py

class DataCollection:
def __init__(self):
self.module = {}
self.items = []

def set\_module(self, module\_dic):  
    self.module = module\_dic

def add\_item(self, item\_dic):  
    self.items.append(item\_dic)

def set\_item(self, item\_dic, item\_name):  
    for item\_num, item in enumerate(self.items):  
        for name, result in item.items():  
            if name == item\_name:  
                self.items\[item\_num\]\[name\] = item\_dic\[name\]  
                break  
    all\_pass = True  
    for item1 in self.items:  
        for result1 in item1.values():  
            if result1 != "p":  
                all\_pass = False  
                break  
    if all\_pass:  
        for module\_name, module\_result in self.module.items():  
            self.module\[module\_name\] = "p"

if __name__ == "__main__":
module_1 = DataCollection()
module_1.set_module({"Test1": "t"})
module_1.add_item({"a": "t"})
module_1.add_item({"b": "t"})
module_1.add_item({"c": "t"})
module_1.add_item({"d": "t"})
module_1.set_item({"a": "p"}, "a")
module_1.set_item({"b": "p"}, "b")
module_1.set_item({"c": "p"}, "c")
module_1.set_item({"d": "p"}, "d")

然后修改刚才生成的treeview3.py

# -*- coding: utf-8 -*-

Form implementation generated from reading ui file 'treeview3.ui'

Created by: PyQt5 UI code generator 5.13.0

WARNING! All changes made in this file will be lost!

from PyQt5 import QtCore, QtGui, QtWidgets
import treeview_data

class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(800, 600)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.treeWidget = QtWidgets.QTreeWidget(self.centralwidget)
self.treeWidget.setGeometry(QtCore.QRect(200, 120, 256, 192))
self.treeWidget.setObjectName("treeWidget")
font = QtGui.QFont()
font.setPointSize(14)
self.treeWidget.headerItem().setFont(0, font)
font = QtGui.QFont()
font.setPointSize(14)
self.treeWidget.headerItem().setFont(1, font)
# item_0 = QtWidgets.QTreeWidgetItem(self.treeWidget)
# brush = QtGui.QBrush(QtGui.QColor(170, 0, 255))
# brush.setStyle(QtCore.Qt.SolidPattern)
# item_0.setBackground(0, brush)
# brush = QtGui.QBrush(QtGui.QColor(0, 255, 0))
# brush.setStyle(QtCore.Qt.SolidPattern)
# item_0.setBackground(1, brush)
# item_1 = QtWidgets.QTreeWidgetItem(item_0)
# item_1 = QtWidgets.QTreeWidgetItem(item_0)
# item_1 = QtWidgets.QTreeWidgetItem(item_0)
# item_1 = QtWidgets.QTreeWidgetItem(item_0)
# item_0 = QtWidgets.QTreeWidgetItem(self.treeWidget)
# item_1 = QtWidgets.QTreeWidgetItem(item_0)
# item_1 = QtWidgets.QTreeWidgetItem(item_0)
# item_1 = QtWidgets.QTreeWidgetItem(item_0)
# item_1 = QtWidgets.QTreeWidgetItem(item_0)
# item_1 = QtWidgets.QTreeWidgetItem(item_0)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)

    self.retranslateUi(MainWindow)  
    QtCore.QMetaObject.connectSlotsByName(MainWindow)

def retranslateUi(self, MainWindow):  
    \_translate = QtCore.QCoreApplication.translate  
    MainWindow.setWindowTitle(\_translate("MainWindow", "MainWindow"))  
    self.treeWidget.headerItem().setText(0, \_translate("MainWindow", "Key"))  
    self.treeWidget.headerItem().setText(1, \_translate("MainWindow", "Value"))  
    \_\_sortingEnabled = self.treeWidget.isSortingEnabled()  
    self.treeWidget.setSortingEnabled(False)  
    self.insert\_data\_to\_tree\_view(\_translate)  
    # self.treeWidget.topLevelItem(0).setText(0, \_translate("MainWindow", "Test1"))  
    # self.treeWidget.topLevelItem(0).setText(1, \_translate("MainWindow", "waiting"))  
    # self.treeWidget.topLevelItem(0).child(0).setText(0, \_translate("MainWindow", "a"))  
    # self.treeWidget.topLevelItem(0).child(0).setText(1, \_translate("MainWindow", "waiting"))  
    # self.treeWidget.topLevelItem(0).child(1).setText(0, \_translate("MainWindow", "b"))  
    # self.treeWidget.topLevelItem(0).child(1).setText(1, \_translate("MainWindow", "waiting"))  
    # self.treeWidget.topLevelItem(0).child(2).setText(0, \_translate("MainWindow", "c"))  
    # self.treeWidget.topLevelItem(0).child(2).setText(1, \_translate("MainWindow", "waiting"))  
    # self.treeWidget.topLevelItem(0).child(3).setText(0, \_translate("MainWindow", "d"))  
    # self.treeWidget.topLevelItem(0).child(3).setText(1, \_translate("MainWindow", "waiting"))  
    # self.treeWidget.topLevelItem(1).setText(0, \_translate("MainWindow", "Test2"))  
    # self.treeWidget.topLevelItem(1).setText(1, \_translate("MainWindow", "waiting"))  
    # self.treeWidget.topLevelItem(1).child(0).setText(0, \_translate("MainWindow", "a"))  
    # self.treeWidget.topLevelItem(1).child(0).setText(1, \_translate("MainWindow", "waiting"))  
    # self.treeWidget.topLevelItem(1).child(1).setText(0, \_translate("MainWindow", "b"))  
    # self.treeWidget.topLevelItem(1).child(1).setText(1, \_translate("MainWindow", "waiting"))  
    # self.treeWidget.topLevelItem(1).child(2).setText(0, \_translate("MainWindow", "c"))  
    # self.treeWidget.topLevelItem(1).child(2).setText(1, \_translate("MainWindow", "waiting"))  
    # self.treeWidget.topLevelItem(1).child(3).setText(0, \_translate("MainWindow", "d"))  
    # self.treeWidget.topLevelItem(1).child(3).setText(1, \_translate("MainWindow", "waiting"))  
    # self.treeWidget.topLevelItem(1).child(4).setText(0, \_translate("MainWindow", "e"))  
    # self.treeWidget.topLevelItem(1).child(4).setText(1, \_translate("MainWindow", "waiting"))  
    self.treeWidget.setSortingEnabled(\_\_sortingEnabled)

def insert\_data\_to\_tree\_view(self, \_translate):  
    list\_objects = \[\]  
    test1 = treeview\_data.DataCollection()  
    test1.set\_module({"Test1": "waiting"})  
    test1.add\_item({"a1": "waiting"})  
    test1.add\_item({"b1": "waiting"})  
    test1.add\_item({"c1": "waiting"})  
    list\_objects.append(test1)

    test2 = treeview\_data.DataCollection()  
    test2.set\_module({"Test2": "waiting"})  
    test2.add\_item({"a2": "waiting"})  
    test2.add\_item({"b2": "waiting"})  
    test2.add\_item({"c2": "waiting"})  
    test2.add\_item({"d2": "waiting"})  
    list\_objects.append(test2)

    test3 = treeview\_data.DataCollection()  
    test3.set\_module({"Test3": "waiting"})  
    test3.add\_item({"a2": "waiting"})  
    test3.add\_item({"b2": "waiting"})  
    test3.add\_item({"c2": "waiting"})  
    test3.add\_item({"d2": "waiting"})  
    list\_objects.append(test3)

    for object\_num, object\_module in enumerate(list\_objects):  
        item\_0 = QtWidgets.QTreeWidgetItem(self.treeWidget)  
        brush = QtGui.QBrush(QtGui.QColor(176, 165, 172))  
        brush.setStyle(QtCore.Qt.SolidPattern)  
        item\_0.setBackground(0, brush)  
        for module\_name, module\_result in object\_module.module.items():  
            brush = QtGui.QBrush(QtGui.QColor(0, 255, 0))  
            brush.setStyle(QtCore.Qt.SolidPattern)  
            item\_0.setBackground(1, brush)  
            self.treeWidget.topLevelItem(object\_num).setText(0, \_translate("MainWindow", module\_name))  
            self.treeWidget.topLevelItem(object\_num).setText(1, \_translate("MainWindow", module\_result))  
        for item\_num, item\_dic in enumerate(object\_module.items):  
            for item\_name, item\_result in item\_dic.items():  
                item\_1 = QtWidgets.QTreeWidgetItem(item\_0)  
                self.treeWidget.topLevelItem(object\_num).child(item\_num).setText(0, \_translate("MainWindow", item\_name))  
                self.treeWidget.topLevelItem(object\_num).child(item\_num).setText(1, \_translate("MainWindow", item\_result))

如果想要使每次运行时,tree都是打开的状态,就在

self.insert_data_to_tree_view(_translate)

后面加一句

self.treeWidget.expandAll()

就行了。

最后的效果就是文章最开头的那样,在循环填写数据的时候,样式就已经设置了,很方便。可以看出,某些情况下画图比较方便,某些情况下代码比较快,具体看自己的需求是怎样的。

另外,如果大家还有什么好的存储数据的方法,欢迎分享交流。