表格与树解决的问题是如何在一个控件中有规律地呈现更多的数据。PyQt提供了两种控件类用于解决该问题,其中一种是表格结构的控件类;另一种是树形结构的控件类。
在通常情况下,一个应用需要和一批数据(比如数组、列表)进行交互,然后以表格的形式输出这些信息,这时就要用到QTableView类了。在QtableView中可以使用自定义的数据模型来显示内容,通过 setModel来绑定数据源。
QTableWidget继承自QTableView,主要区别是 QTableView可以使用自定义的数据模型来显示内容(先要通过setModel来绑定数据源),而 QTableWidget只能使用标准的数据模型,并且其单元格数据是通过QTableWidgetItem对象来实现的。通常使用QTableWidget就能够满足要求。
QTableView类的继承结构

QTableView控件可以绑定一个模型数据用于更新控件上的内容,可用的模式:
| 名称 | 含义 |
|---|---|
| QStringListModel | 存储一组字符串 |
| QStandardItemModel | 存储任意层次结构的数据 |
| QDirModel | 对文件系统进行封装 |
| QSqlQueryModel | 对SQL的查询结果集进行封装 |
| QSqlTableModel | 对SQL中的表格进行封装 |
| QSqlRelationalTableModel | 对带有外键的SQL表格进行封装 |
| QSortFilterProxyModel | 对模型中的数据进行排序或过滤 |
案例 QTableView的使用
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import sys
class Table(QWidget):
def __init__(self,arg = None):
super(Table, self).__init__(arg)
self.setWindowTitle("QTableView表格视图控件案例")
self.resize(500 , 300)
self.model = QStandardItemModel(4 , 4)
self.model.setHorizontalHeaderLabels(["标题1","标题2","标题3","标题4"])
for row in range(4):
for colunm in range(4):
item = QStandardItem("row %s , column %s" % (row,colunm))
self.model.setItem(row , colunm , item)
self.tableView = QTableView()
self.tableView.setModel(self.model)
dlgLayout = QVBoxLayout()
dlgLayout.addWidget(self.tableView)
self.setLayout(dlgLayout)
if __name__ == '__main__':
from pyqt5_plugins.examples.exampleqmlitem import QtCore
QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
app = QApplication(sys.argv)
win = Table()
win.show()
sys.exit(app.exec_())

可以看出,表格没有填满窗口,每列可以自由拉动,但是可能会出现滚动条。
把表格填满窗口
self.tableView.horizontalHeader().setStretchLastSection(True)
self.tableView.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)

添加数据
self.model.appendRow([
QStandardItem("row %s , column %s" % (11, 11)),
QStandardItem("row %s , column %s" % (11, 11)),
QStandardItem("row %s , column %s" % (11, 11)),
QStandardItem("row %s , column %s" % (11, 11)),
])

删除当前选中的数据
第一种方法
indexs = self.tableView.selectionModel().selection().indexes()
if len(indexs) > 0:
# 取第一行的索引
index = indexs[0]
self.model.removeRows(index.row() , 1)
第二种方法
index = self.tableView.currentIndex()
print(index.row())
self.model.removeRow(index.row())
OListView类用于展示数据,它的子类是 QListWidget。QListView是基于模型(Model)的,需要程序来建立模型,然后再保存数据。
QListWidget是一个升级版本的 QListView,它已经建立了一个数据存储模型(OListWidgetItem),直接调用addItem()函数,就可以添加条目(Item)。
QListView类中的常用方法
| 方法 | 描述 |
|---|---|
| setModel() | 用来设置View所关联的Model,可以Python原生的list作为数据源Model |
| selectedItem() | 选中Model中的条目 |
| isSelected() | 判断Model中的某条目是否被选中 |
QListView类中的常用信号
| 信号 | 含义 |
|---|---|
| clicked | 当单击某项时,信号被反射 |
| doubleClicked | 当双击某项时,信号被发射 |
案例 QListView的使用
from PyQt5.QtWidgets import QApplication , QWidget , QVBoxLayout , QListView , QMessageBox
from PyQt5.QtCore import QStringListModel
import sys
class ListViewDemo(QWidget):
def __init__(self,parent = None):
super(ListViewDemo, self).__init__(parent)
self.setWindowTitle("QListView案例")
self.resize(300 , 270)
layout = QVBoxLayout()
listView = QListView()
slm = QStringListModel()
self.qlist = ['Item1','Item2','Item3','Item4']
slm.setStringList(self.qlist)
listView.setModel(slm)
listView.clicked.connect(self.clicked)
layout.addWidget(listView)
self.setLayout(layout)
def clicked(self , qModelIndex):
QMessageBox.information(self,"ListWidget","你选择了:" + self.qlist[qModelIndex.row()])
if __name__ == '__main__':
from pyqt5_plugins.examples.exampleqmlitem import QtCore
QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
app = QApplication(sys.argv)
win = ListViewDemo()
win.show()
sys.exit(app.exec_())

QListWidet类是一个基于条目的接口,用于从列表中添加或删除条目。列表中的每个条目都是一个QListWidgetItem对象。QListWidget可以设置为多重选择。
QListWidget类中的常用方法
| 方法 | 描述 |
|---|---|
| addItem() | 在列表中添加 QListWidgetItem对象或字符串 |
| addItems() | 添加列表中的每个条目 |
| insertItem() | 在指定的索引处插入条目 |
| clear() | 删除列表的内容 |
| setCurrentItem() | 设置当前所选条目 |
| sortItems() | 按升序重新排列条目 |
QListWidget类中的常用信号
| 信号 | 含义 |
|---|---|
| currentItemChanged | 当列表的条目发生改变时发射此信号 |
| itemClicked | 当点击列表中的条目时发射此信号 |
案例 QListWidget的使用
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class ListWidget(QListWidget):
def clicked(self,item):
QMessageBox.information(self,"ListWidget","你选择了:" + item.text())
if __name__ == '__main__':
from pyqt5_plugins.examples.exampleqmlitem import QtCore
QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
app = QApplication(sys.argv)
listWidget = ListWidget()
listWidget.resize(300 , 120)
listWidget.addItem("Item 1")
listWidget.addItem("Item 2")
listWidget.addItem("Item 3")
listWidget.addItem("Item 4")
listWidget.setWindowTitle("QListWidget案例")
listWidget.itemClicked.connect(listWidget.clicked)
listWidget.show()
sys.exit(app.exec_())

QTableWidget是Qt程序中常用的显示数据表格的空间,类似于C#中的DataGrid。QTableWidget是 QTableView 的子类,它使用标准的数据模型,并且其单元格数据是通过QTableWidgetItem对象来实现的。使用QTableWidget 时就需要QTableWidgetItem,用来表示表格中的一个单元格,整个表格就是用各单元格构建起来的。
QTableWidget类中的常用方法
| 方法 | 描述 |
|---|---|
| setRowCount(int row) | 设置QTableWidget表格控件的行数 |
| setColumnCount(int col) | 设置QTableWidget表格控件的列数 |
| setHorizontalHeaderLabels() | 设置QTableWidget表格控件的水平标签 |
| setVerticalHeaderLabelsO | 设置QTableWidget表格控件的垂直标签 |
| setItem(int, int, QTableWidgetItem) | 在 QTableWidget表格控件的每个选项的单元空间里添加控件 |
| horizontalHeader() | 获得QTableWidget表格控件的表格头,以便执行隐藏 |
| rowCount() | 获得QTableWidget表格控件的行数 |
| columnCount() | 获得QTableWidget表格控件的列数 |
| setEditTriggers(EditTriggers triggers) | 设置表格是否可编辑。设置编辑规则的枚举值 |
| setSelectionBehavior | 设置表格的选择行为 |
| setTextAlignment() | 设置单元格内文字的对齐方式 |
| setSpan(int row, int column, int rowSpanCount,int columnSpanCount) | 合并单元格,要改变单元格的第row行第column列,要合并rowSpanCount行数和columnSpanCount列数。row:要改变的单元格行数; |
| column:要改变的单元格列数;rowSpanCount:需要合并的行数 ;columnSpanCount:需要合并的列数 | |
| setShowGrid() | 在默认情况下,表格的显示是有网格线的。True:显示网格线;False:不显示网格线 |
| setColumnWidth(int column, int width) | 设置单元格行的宽度 |
| setRowHeight(int row, int height) | 设置单元格行的高度 |
编辑规则的枚举值类型
| 选项 | 值 | 描述 |
|---|---|---|
| QAbstractItemView.NoEditTriggers0No | 0 | 不能对表格内容进行修改 |
| QAbstractItemView.CurrentChanged1Editing | 1 | 任何时候都能对单元格进行修改 |
| QAbstractItemView.DoubleClicked2Editing | 2 | 双击单元格 |
| QAbstractItem View.SelectedClicked4Editing | 4 | 单击已选中的内容 |
| QAbstractItemView.EditKeyPressed8Editing | 8 | 当修改键被按下时修改单元格 |
| QAbstractltemVew.AnyKeyPressed16Editing | 16 | 按任意键修改单元格 |
| QAbstractltemView.AllEditTriggers31Editing | 31 | 包括以上所有条件 |
表格的选择行为的枚举值类型
| 选项 | 值 | 描述 |
|---|---|---|
| QAbstractItemView.SelectItems0Selecting | 0 | 选中单个单元格 |
| QAbstractItemView.SelectRows1Selecting | 1 | 选中一行 |
| QAbstractItem View.SelectColumns2Selecting | 2 | 选中一列 |
单元格文本的水平对齐方式
| 选项 | 描述 |
|---|---|
| Qt.AlignLeft | 将单元格的内容沿单元格的左边缘对齐 |
| Qt.AlignRight | 将单元格的内容沿单元格的右边缘对齐 |
| Qt.AlignHCenter | 在可用空间上,居中显示在水平方向上 |
| Qt.AlignJustify | 将文本在可用空间中对齐,默认是从左到右的 |
单元格文本的垂直对齐方式
| 选项 | 描述 |
|---|---|
| Qt.AlignTop | 与顶部对齐 |
| Qt.AlignBottom | 与底部对齐 |
| Qt.AlignVCenter | 在可用空间中,居中显示在垂直方向上 |
| Qt.AlignBaseline | 与基线对齐 |
如果要设置水平和垂直对齐方式,比如在表格空间内上下、左右居中对齐,那么只要使用Qt.AlignHCenter 和 Qt.AlignVCenter即可。
基本用法
import sys
from PyQt5.QtWidgets import (QWidget , QTableWidget , QHBoxLayout , QApplication,QTableWidgetItem)
class Table(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setWindowTitle("QTableWidget案例")
self.resize(400 , 300)
conLayout = QHBoxLayout()
tableWidget = QTableWidget()
tableWidget.setRowCount(4)
tableWidget.setColumnCount(3)
conLayout.addWidget(tableWidget)
tableWidget.setHorizontalHeaderLabels(["姓名","性别","体重(kg)"])
newItem = QTableWidgetItem("张三")
tableWidget.setItem(0 , 0 ,newItem)
newItem = QTableWidgetItem("男")
tableWidget.setItem(0 , 1 , newItem)
newItem = QTableWidgetItem("70")
tableWidget.setItem(0 , 2, newItem)
self.setLayout(conLayout)
if __name__ == '__main__':
from pyqt5_plugins.examples.exampleqmlitem import QtCore
QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
app = QApplication(sys.argv)
win = Table()
win.show()
sys.exit(app.exec_())

① 在默认情况下, 表格里的字符串是可以更改的
② 生成表格,要先初始化行号和列号,再设置表格的表头标签,否则没有效果
设置表格头为伸缩模式:
tableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)

将表格变为禁止编辑
tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)

设置表格整行选中
【表格默认选中是某个单个单元格】
tableWidget.setSelectionBehavior(QAbstractItemView.SelectRows)

将行和列的宽度、高度设置为与所显示内容的宽度、高度相匹配
这里先把伸缩模式关闭,不然没效果
tableWidget.resizeColumnsToContents()
tableWidget.resizeRowsToContents()

表格头的显示与隐藏
# 垂直方向
tableWidget.verticalHeader().setVisible(False)
# 水平方向
tableWidget.horizontalHeader().setVisible(False)

在单元格中放置控件
QTableWidget不仅允许往单元格中放置文字,还允许放置控件,通过TableWidget.setItem()来添加PyQt的基本控件。
conBox = QComboBox()
conBox.addItem("男")
conBox.addItem("女")
conBox.setStyleSheet("QComboBox{margin:3px};")
tableWidget.setCellWidget(0,1,conBox)
searchBtn = QPushButton("修改")
searchBtn.setDown(True)
searchBtn.setStyleSheet("QPushButton{margin:3px};")
tableWidget.setCellWidget(0,2,searchBtn)

从表格中快速定位到指定行
当tableWidget表格的行数很多时,可以通过输入行号进行直接定位并显示,比如输入10,就直接显示第10行。
import sys
from PyQt5.QtWidgets import *
from PyQt5 import QtCore
from PyQt5.QtGui import QColor, QBrush
class Table(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setWindowTitle("QTableWidget 例子")
self.resize(600, 800);
conLayout = QHBoxLayout()
tableWidget = QTableWidget()
tableWidget.setRowCount(30)
tableWidget.setColumnCount(4)
conLayout.addWidget(tableWidget)
for i in range(30):
for j in range(4):
itemContent = '(%d,%d)' % (i, j)
tableWidget.setItem(i, j, QTableWidgetItem(itemContent))
self.setLayout(conLayout)
# 遍历表查找对应的item
text = "(10,1)"
items = tableWidget.findItems(text, QtCore.Qt.MatchExactly)
item = items[0]
# 选中单元格
# item.setSelected( True)
# 设置单元格的背景颜色为红色
item.setForeground(QBrush(QColor(255, 0, 0)))
row = item.row()
# 滚轮定位过去,快速定位到第17行
tableWidget.verticalScrollBar().setSliderPosition(row)
if __name__ == '__main__':
from pyqt5_plugins.examples.exampleqmlitem import QtCore
QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
app = QApplication(sys.argv)
win = Table()
win.show()
sys.exit(app.exec_())

设置单元格
设置单元格文本颜色
import sys
from PyQt5.QtWidgets import (QWidget, QTableWidget, QHBoxLayout, QApplication, QTableWidgetItem)
from PyQt5.QtGui import QBrush, QColor, QFont
class Table(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setWindowTitle("QTableWidget 例子")
self.resize(430, 230);
conLayout = QHBoxLayout()
tableWidget = QTableWidget()
tableWidget.setRowCount(4)
tableWidget.setColumnCount(3)
conLayout.addWidget(tableWidget)
tableWidget.setHorizontalHeaderLabels(['姓名', '性别', '体重(kg)'])
newItem = QTableWidgetItem("张三")
newItem.setForeground(QBrush(QColor(255, 0, 0)))
tableWidget.setItem(0, 0, newItem)
newItem = QTableWidgetItem("男")
newItem.setForeground(QBrush(QColor(255, 0, 0)))
tableWidget.setItem(0, 1, newItem)
newItem = QTableWidgetItem("70")
newItem.setForeground(QBrush(QColor(255, 0, 0)))
tableWidget.setItem(0, 2, newItem)
self.setLayout(conLayout)
if __name__ == '__main__':
from pyqt5_plugins.examples.exampleqmlitem import QtCore
QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
app = QApplication(sys.argv)
win = Table()
win.show()
sys.exit(app.exec_())

将字体加粗
newItem.setFont(QFont("Times",12,QFont.Black))

设置单元格的排序方式
## DescendingOrder 降序
## AscendingOrder 升序
# tableWidget.sortItems(2,Qt.DescendingOrder)
tableWidget.sortItems(2, Qt.AscendingOrder)

设置单元格文本的对齐方式
使用QTableWidgetItem.setTextAlignment(int)函数设置单元格文本的对齐方式。
newItem.setTextAlignment(Qt.AlignRight | Qt.AlignBottom)

合并单元格效果的实现
tableWidget.setSpan(0 , 0 , 3 , 1)

设置单元格的大小
# 将第一列的单元格宽度设置为150
tableWidget.setColumnWidth(0 , 150)
# 将第一行的单元格高度设置为120
tableWidget.setRowHeight(0 , 120)

在表格中不显示分割线
默认显示
tableWidget.setShowGrid(False)

为单元格添加图片
进行这步前,需要调整一下表格的布局
newItem = QTableWidgetItem(QIcon("images/bao1.png"), "背包")
tableWidget.setItem(0, 3, newItem)

改变单元格中显示的图片大小
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class Table(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setWindowTitle("QTableWidget 例子")
self.resize(1000, 900);
conLayout = QHBoxLayout()
table = QTableWidget()
table.setColumnCount(3)
table.setRowCount(5)
table.setHorizontalHeaderLabels(['图片1', '图片2', '图片3'])
table.setEditTriggers(QAbstractItemView.NoEditTriggers)
table.setIconSize(QSize(300, 200));
for i in range(3): # 让列宽和图片相同
table.setColumnWidth(i, 300)
for i in range(5): # 让行高和图片相同
table.setRowHeight(i, 200)
for k in range(15): # 27 examples of DDA
i = k / 3
j = k % 3
item = QTableWidgetItem()
item.setFlags(Qt.ItemIsEnabled) # 用户点击时表格时,图片被选中
icon = QIcon(r'images/bao%d.png' % k)
item.setIcon(QIcon(icon))
print('e/icons/%d.png i=%d j=%d' % (k, i, j))
table.setItem(i, j, item)
conLayout.addWidget(table)
self.setLayout(conLayout)
if __name__ == '__main__':
# from pyqt5_plugins.examples.exampleqmlitem import QtCore
# QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
app = QApplication(sys.argv)
win = Table()
win.show()
sys.exit(app.exec_())

获得单元格的内容
通过实现 itemClicked (QTableWidgetIltem *)信号的槽函数,可以获得所点击的单元格的引用,进而获得其中的内容。

支持右键菜单
import sys
from PyQt5.QtWidgets import (QMenu, QPushButton, QWidget, QTableWidget, QHBoxLayout, QApplication, QTableWidgetItem,
QHeaderView)
from PyQt5.QtCore import QObject, Qt
class Table(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setWindowTitle("QTableWidget 例子")
self.resize(500, 300);
conLayout = QHBoxLayout()
self.tableWidget = QTableWidget()
self.tableWidget.setRowCount(5)
self.tableWidget.setColumnCount(3)
conLayout.addWidget(self.tableWidget)
self.tableWidget.setHorizontalHeaderLabels(['姓名', '性别', '体重'])
self.tableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
newItem = QTableWidgetItem("张三")
self.tableWidget.setItem(0, 0, newItem)
newItem = QTableWidgetItem("男")
self.tableWidget.setItem(0, 1, newItem)
newItem = QTableWidgetItem("80")
self.tableWidget.setItem(0, 2, newItem)
# 表格中第二行记录
newItem = QTableWidgetItem("李四")
self.tableWidget.setItem(1, 0, newItem)
newItem = QTableWidgetItem("女")
self.tableWidget.setItem(1, 1, newItem)
newItem = QTableWidgetItem("75")
self.tableWidget.setItem(1, 2, newItem)
self.tableWidget.setContextMenuPolicy(Qt.CustomContextMenu) ######允许右键产生子菜单
self.tableWidget.customContextMenuRequested.connect(self.generateMenu) ####右键菜单
self.setLayout(conLayout)
def generateMenu(self, pos):
# rint( pos)
row_num = -1
for i in self.tableWidget.selectionModel().selection().indexes():
row_num = i.row()
if row_num < 2:
menu = QMenu()
item1 = menu.addAction(u"选项一")
item2 = menu.addAction(u"选项二")
item3 = menu.addAction(u"选项三")
action = menu.exec_(self.tableWidget.mapToGlobal(pos))
if action == item1:
print('您选了选项一,当前行文字内容是:', self.tableWidget.item(row_num, 0).text(),
self.tableWidget.item(row_num, 1).text(), self.tableWidget.item(row_num, 2).text())
elif action == item2:
print('您选了选项二,当前行文字内容是:', self.tableWidget.item(row_num, 0).text(),
self.tableWidget.item(row_num, 1).text(), self.tableWidget.item(row_num, 2).text())
elif action == item3:
print('您选了选项三,当前行文字内容是:', self.tableWidget.item(row_num, 0).text(),
self.tableWidget.item(row_num, 1).text(), self.tableWidget.item(row_num, 2).text())
else:
return
if __name__ == '__main__':
from pyqt5_plugins.examples.exampleqmlitem import QtCore
QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
app = QApplication(sys.argv)
win = Table()
win.show()
sys.exit(app.exec_())

QTreeWidget类实现了树形结构。
QTreeWidget类的继承结构:
QWidget → QFrame → QAbstractScrollArea → QAbstractItemView → QAbstractScrollArea → QAbstractItemView → QTreeView → QTreeWidget
QTreeWidget类中的常用方法
| 方法 | 描述 |
|---|---|
| setColumnWidth(int column , int width) | 将指定列的宽度设置为给定的值;Column,指定的列;Width,指定列的宽度 |
| insertTopLevelItems() | 在视图的顶层索引中插入项目列表 |
| expandAll() | 展开所有的树形节点 |
| invisibelRootItem() | 返回树形控件中不可见的根选项(Root Item) |
| selectedItems() | 返回所有选定的非隐藏项目的列表 |
QTreeWidgetItem类中的常用方法
| 方法 | 描述 |
|---|---|
| addChild() | 将子项追加到子列表中 |
| setText() | 设置显示的节点文本 |
| Text() | 返回显示的节点文本 |
| setCheckState(column , state) | 设置指定列的选中状态:Qt.Checked,节点选中;Qt.Unchecked,节点未选中 |
| setIcon | 在指定的列中显示图标 |
树形结构的实现
树形结构是通过QTreeWidget和 QTreeWidgetItem类实现的,其中QTreeWidgetltem类实现了节点的添加。
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QIcon, QBrush, QColor
from PyQt5.QtCore import Qt
class TreeWidgetDemo(QMainWindow):
def __init__(self, parent=None):
super(TreeWidgetDemo, self).__init__(parent)
self.setWindowTitle('TreeWidget 例子')
self.tree = QTreeWidget()
# 设置列数
self.tree.setColumnCount(2)
# 设置头的标题
self.tree.setHeaderLabels(['Key', 'Value'])
# 设置根节点
root = QTreeWidgetItem(self.tree)
root.setText(0, 'root')
root.setIcon(0, QIcon("./images/root.png"))
# 设置列宽
self.tree.setColumnWidth(0, 160)
### 设置节点的背景颜色
# brush_red = QBrush(Qt.red)
# root.setBackground(0, brush_red)
# brush_green = QBrush(Qt.green)
# root.setBackground(1, brush_green)
# 设置子节点1
child1 = QTreeWidgetItem(root)
child1.setText(0, 'child1')
child1.setText(1, 'ios')
child1.setIcon(0, QIcon("../images/IOS.png"))
# 设置子节点2
child2 = QTreeWidgetItem(root)
child2.setText(0, 'child2')
child2.setText(1, '')
child2.setIcon(0, QIcon("../images/android.png"))
# 设置子节点3
child3 = QTreeWidgetItem(child2)
child3.setText(0, 'child3')
child3.setText(1, 'android')
child3.setIcon(0, QIcon("../images/music.png"))
self.tree.addTopLevelItem(root)
# 结点全部展开
self.tree.expandAll()
self.setCentralWidget(self.tree)
if __name__ == '__main__':
from pyqt5_plugins.examples.exampleqmlitem import QtCore
QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
app = QApplication(sys.argv)
win = TreeWidgetDemo()
win.show()
sys.exit(app.exec_())

设置节点状态
可以使用QTreeWidgetItem的setCheckState()函数设置节点是否为选中状态。
child1.setCheckState(0, Qt.Checked)

设置节点的背景颜色
可以使用QBrush类来设置节点的背景颜色。
brush_red = QBrush(Qt.red)
root.setBackground(0,brush_red)
brush_green = QBrush(Qt.green)
root.setBackground(1,brush_green)

给节点添加响应事件
from PyQt5.QtWidgets import *
import sys
class TreeWidgetDemo(QMainWindow):
def __init__(self, parent=None):
super(TreeWidgetDemo, self).__init__(parent)
self.setWindowTitle('TreeWidget 例子')
self.tree = QTreeWidget()
# 设置列数
self.tree.setColumnCount(2)
# 设置头的标题
self.tree.setHeaderLabels(['Key', 'Value'])
root = QTreeWidgetItem(self.tree)
root.setText(0, 'root')
root.setText(1, '0')
child1 = QTreeWidgetItem(root)
child1.setText(0, 'child1')
child1.setText(1, '1')
child2 = QTreeWidgetItem(root)
child2.setText(0, 'child2')
child2.setText(1, '2')
child3 = QTreeWidgetItem(root)
child3.setText(0, 'child3')
child3.setText(1, '3')
child4 = QTreeWidgetItem(child3)
child4.setText(0, 'child4')
child4.setText(1, '4')
child5 = QTreeWidgetItem(child3)
child5.setText(0, 'child5')
child5.setText(1, '5')
self.tree.addTopLevelItem(root)
self.tree.clicked.connect(self.onTreeClicked)
self.setCentralWidget(self.tree)
def onTreeClicked(self, qmodelindex):
item = self.tree.currentItem()
print("key=%s ,value=%s" % (item.text(0), item.text(1)))
if __name__ == '__main__':
from pyqt5_plugins.examples.exampleqmlitem import QtCore
QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
app = QApplication(sys.argv)
win = TreeWidgetDemo()
win.show()
sys.exit(app.exec_())

QTreeWidgetItem类的节点是一个个添加的,这样做有时很不方便,特别是当窗口中产生比较复杂的树形结构时,一般都是通过OTreeView类来实现的,而不是QTreeWidget类。OTreeView类与 QTreeWidget类最大的区别就是,QTreeView类可以使用操作系统提供的定制模式,比如文件系统盘的树列表。
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
if __name__ == '__main__':
from pyqt5_plugins.examples.exampleqmlitem import QtCore
QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
app = QApplication(sys.argv)
model = QDirModel()
tree = QTreeView()
tree.setModel(model)
tree.setWindowTitle("QTreeView案例")
tree.resize(640,480)
tree.show()
sys.exit(app.exec_())
