Tree Widget -- 基本方法
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()
就行了。
最后的效果就是文章最开头的那样,在循环填写数据的时候,样式就已经设置了,很方便。可以看出,某些情况下画图比较方便,某些情况下代码比较快,具体看自己的需求是怎样的。
另外,如果大家还有什么好的存储数据的方法,欢迎分享交流。