树视图QTreeView
QTreeWidget 包含内置模型,可以创建简单的树。本节介绍纯视图的QTreeView,可以创建更复杂的树。
树视图控件 QTreeView 以树列表的形式显示文件系统模型关联的本机文件系统,显示出本机的目录、文件名、文件大小等信息,也可以以层级结构形式显示其他类型的数据模型。
用QTreeView类创建树视图控件的方法如下,其中parent是继承自QWidget 的窗口或容器控件。
from PySide6.QtWidgets import QTreeView
QTreeView(parent: Union[PySide6.QtWidgets.QWidget,NoneType]= None)-> None
树视图QTreeView的方法
树视图控件QTreeView 的常用方法如表所示,主要方法介绍如下
- 用setModel(QAbstractItemModel)方法可以给树视图控件设置关联的数据模型
- 用setrootIndex(QModelIndex)方法可以设置树视图控件根部指向的模型数据位置。
- 用setItemsExpandable(bool)方法设置是否可以展开节点;
- 用setExpanded(QModelIndex;bool)方法设置展开或折叠某节点;
- 用expand(QModelIndex)方法展开某节点;用expandAll()方法展开所有节点;
- 用collapse(QModelIndex)方法折叠某节点;
- 用collapseAl1()方法折叠所有节点;
- 用setExpandsOnDoubleClick(bool)方法设置双击节点时是否展开节点。
- 展开或折叠节点时,将会发送expanded(QModelIndex)信号或 collapsed(QModelIndex)信号。
- 用setColumnHidden(column;int,hide:bool)方法可以设置隐藏或显示某列,
- 用showColumn(column;int)方法和hideColumn(column:int)方法可以显示和隐藏指定的列。
- 用setColumnWidth(int,int)方法设置列的宽度,用setUniformRowHeights(bool)方法设置行是否有统一的高度。"
QTreeView的方法及参数类型 | 说 明 |
---|---|
setModel(QAbstractItemModel) | 设置数据模型 |
setSelectionModel(QItemSelectionModel) | 设置选择模型 |
selectionModel() | 获取选择模型 QItemSelectionModel |
ctSelection(reet: QRect,command: QItemSelectionModel.SelectionFlags) | 选择指定范图内的数据项 |
setrootIndex(QModellndex) | 设置根部的索引 |
setrootIsDecorated(bool) | 设置根部是否有折叠或展开标识 |
rootlsDecorated() | 获取根部是否有折叠或展开标识 |
[slot]collapse(QModellndex) | 折叠节点 |
[slot]collapseAII() | 折叠所有节点 |
[slot]expand(QModellndex) | 展开节点 |
isExpanded(QModelIndex) | 获取节点是否已经展开 |
[slot]expandAII() | 股开所有节点 |
[slot]expandRecursively(QModelIndex,depth=-1) | 逐级展开,腰开探度是 depth。一1表示展开所有节点,0表示只展开本层 |
[slot]expandToDepth(depth:int) | 展开到指定的深度 |
[slot]hideColumn(column:int) | 隐藏列 |
[slot]showColumn(column:int) | 显示列 |
indexAbove(QModelIndex) | 获取某索引之前的索引 |
indexAt(QPoint) | 获取某个点处的索引 |
indexBelow(QModelIndex) | 获取某索引之后的索引 |
selectAII() | 全部选择 |
selectedIndexes() | 获取选中的项的行列表 List[int] |
setAnimated(bool) | 设置展开或折叠时是否比较连贯 |
isAnimated() | 获取展开或折叠时是否比较连贯 |
setColumnHidden(column:int,hide: bool) | 设置是否隐藏列 |
isColumnHidden(column:int) | 获取列是否隐藏 |
setRowHidden(row: int,parent: QModelIndex,hide:bool) | 设置相对于QModelIndex的第int行是否隐藏 |
isRowHidden(row: int,parent: QModelIndex) | 获取行是否隐藏 |
setColumnWidth(column: int,width: int) | 设置列的宽度 |
columnWidth(column:int) | 获取列的宽度 |
rowHeight(index: QModelIndex) | 获取行的高度 |
setItemsExpandable(enable:bool) | 设置是否可以展开节点 |
itemsExpandable() | 获取节点是否可以展开 |
setExpanded(QModelIndex,bool) | 设置是否展开某节点 |
setExpandsOnDoubleClick(bool) | 设置双击时是否展开节点 |
setFirstColumnSpanned(row: int,parent: QModelIndex,span:bool) | 设置某行的第1列的内容是否占据所有列 |
isFirstColumnSpanned(int,QModelIndex) | 获取某行的第1列的内容是否占据所有列 |
setHeader(QHeaderView) | 设置表头 |
header() | 获取表头 |
setHeaderHidden(bool) | 设置是否隐藏表头 |
setIndentation(int) | 设置缩进量 |
indentation() | 获取缩进量 |
resetIndentation() | 重置缩进量 |
setAutoExpandDelay(delay:int) | 拖放操作中设置项打开的延迟时间(毫秒) |
autoExpandDelay() | 获取项打开的延迟时间,如为负则不能打开 |
setAllColumnsShowFocus(enable:bool) | 设置所有列是否显示键盘焦点,否则只有一列显示 焦点 |
allColumnsShowFocus() | 获取所有列是否显示键盘焦点 |
setItemsExpandable(bool) | 设置是否可以展开节点 |
setUniformRowHeights(uniform:bool) | 设置项是否有相同的高度 |
uniformRowHeights() | 获取项是否有相同的高度 |
setWordWrap(on:bool) | 设置一个单词是否可以写到两行上 |
serTextElideMode(mode:Qt.TextElideMode) | 设置省略号"…"的位置,参数可取Qt.ElideLelt、Qt.ElideRight、Qt.ElideMiddle 或 Qt.ElideNone |
setTreePosition(logicalIndex:int) | 设置树的位置 |
treePosition() | 获取树的位置 |
setSortingEnabled(bool) | 设置是否可以进行排序 |
isSortingEnabled() | 获取是否可以排序 |
[slot]sortByColumn(int,Qt.SortOrder) | 按列进行排序 |
[slotJresizeColumnToContents(column:int) | 根据内容调整列的尺寸 |
scrollContentsBy(dx:int,dy:int) | 将内容移动指定的距离 |
setUniformRowHeights(bool) | 设置行是否有统一高度 |
QTreeView 结合 QStandardItemModel 的使用
本节先介绍QTreeView 结合 QStandardItemModel 的使用方法,并且会复制先前案例;然后结合QFileSystemModel来说明QTreeView 显示文件目录结构的使用方法,
该模型会也会结合QListView和 QTableView 一起使用。
TreeView 实现了QAbstractItemView 定义的接口,以允许它显示从QAbstractItemModel派生的模型提供的数据。QTreeView 类的继承结构如图5-14所示。对QTreeView 的定位仅仅用来显示数据,这里只提供一些用来显示数据的基本操作。
当然,也可以参考 QListVicw 和 QTableView 的相关内容添加更复杂的操作
和 QTableView 一样,使用 QTreeView 需要绑定模型,这里绑定了标准模型QStandardItemModel和选择模型 QItemSelectionModel:
self.treeViewQtreeView()
self.model = QStandardItemModel()
self.treeView.setModel(self .model)
self.selectModel = OItemSelectionModel()
self.treeView.setSelectionModel(self.selectModel)
接下来设置树的列数,并快速设置标题:
# 设置列数
self.model.setColumnCount(3)
# 设置树形控件头部的标题
self.model,setHorizontalHeaderLabels([学科,,姓名',分数'])
开始添加第1个根节点:
# 添加根节点
root = QStandardItem1学科)
rootList = [root,QStandardItem(姓名),QStandardItem('分数')]
self.model.appendRow(rootList)
对于每个节点,都可以通过函数 setIcon0、setBackground0等修改外观:
# 设置图标
root.setIcon(QIcon('./images/root.png'))
# 设置根节点的背景色
root.setBackground(QBrush(Qt.blue))
rootList[1].setBackground(QBrush(Qt.yellow))
rootList[2].setBackground(OBrush(Qt.red))
添加子节点,相关内容和代码如下:
#一级节点
for subject in ['语文','数学','外语','"综合']:
itemSubject = QStandardItem(subject)
root.appendRow([itemSubject,QStandardItem(),QStandardItem()])
#二级节点
for name in ['张三','李四','王五','赵六']:
itemName = QStandardItem(name)
itemName.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsUserCheckable | Qt.ItemIsEditable)
score = random.random()* 40 +60
itemScore = QStandardItem(str(score)[:5])
......
其他的设置如下:
#设置树形控件的列的宽度
self.treeView.setColumnWidth(0,150)
#展开全部节点
self.treeView.expandAll()
# 启用排序
self.treeView.setSortingEnabled(True)
树视图控件QTreeView的信号
树视图控件QTreeView的信号如表所示
QTreeView的信号及参数类型 | 说明 |
---|---|
collapsed(QModelIndex) | 折叠节点时发送信号 |
expanded(QModelIndex) | 展开节点时发送信号 |
activated(QModelIndex) | 数据项活跃时发送信号 |
clicked(QModelIndex) | 单击数据项时发送信号 |
doubleClicked(QModelIndex) | 双击数据项时发送信号 |
entered(QModelIndex) | 光标进入数据项时发送信号 |
iconSizeChanged(QSize) | 图标尺寸发生变化时发送信号 |
pressed(QModelIndex) | 按下鼠标按键时发送信号 |
viewportEntered() | 光标进入树视图时发送信号 |
树视图QTreeView案例
如图所示,本案例创建了上、下两个QTreeView实例,绝大部分操作都是基于上面的实例,下面的作为对照组,当上面的实例发生变化时下面的实例会自动改变,这也体现了使用模型/视图框架的优越性,即不用维护两套数据本案例的内容之前已经介绍过,此处不再赘述。
QFileSystemModel提供对本地文件系统的访问,同时提供重命名、删除文件和目录创建新目录的功能。在最简单的情况下,QFileSystemModel 可以与合适的小控件(一般是QTreeView、QListView 和 QTableView)一起使用,作为浏览器或过滤器的一部分。OFileSystemModel 可以使用 QAbstractItemModel 提供的标准接口访问,但它也提供了一些管理目录的特色方法,如使用函数 fileInfo0isDir0fileName0和filePath0可以提供底层文件和目录信息;使用函数 mkdir()和 rmdir()可以创建和删除目录,其简单案例如下。
from PySide6.QtWidgets import *
from PySide6.QtGui import *
from PySide6.QtCore import *
import sys
import random
import os
os.chdir(os.path.dirname(__file__))
class QTreeViewDemo(QMainWindow):
def __init__(self,parent=None):
super(QTreeViewDemo,self).__init__(parent)
self.setWindowTitle("QTreeView案例")
self.resize(500,600)
self.text = QPlainTextEdit('用来显示QTreeView相关信息:')
self.treeView = QTreeView()
self.model = QStandardItemModel()
self.treeView.setModel(self.model)
self.selectModel = QItemSelectionModel()
self.treeView.setSelectionModel(self.selectModel)
# 对照组
self.treeView2 = QTreeView()
self.treeView2.setModel(self.model)
layout = QVBoxLayout(self)
layout.addWidget(self.treeView)
layout.addWidget(self.text)
layout.addWidget(self.treeView2)
widget = QWidget()
self.setCentralWidget(widget)
widget.setLayout(layout)
self.initItem()
# selection
# self.listWidget.setSelectionMode(QAbstractItemView.SingleSelection)
self.treeView.setSelectionMode(QAbstractItemView.ExtendedSelection)
# self.treeWidget.setSelectionBehavior(QAbstractItemView.SelectRows)
self.treeView.setSelectionBehavior(QAbstractItemView.SelectItems)
self.treeView.setMouseTracking(True)
# 信号与槽
self.treeView.clicked.connect(self.onClicked)
self.treeView.collapsed[QModelIndex].connect(lambda index: self.text.appendPlainText(f'{self.model.data(index)}: 触发了collapsed信号'))
self.treeView.expanded[QModelIndex].connect(lambda index: self.text.appendPlainText(f'{self.model.data(index)}: expanded信号'))
def initItem(self):
# 设置列数
self.model.setColumnCount(3)
# 设置树形控件头部的标题
self.model.setHorizontalHeaderLabels(['学科','姓名','分数'])
# 设置根节点
root = QStandardItem('学科')
rootList = [root,QStandardItem('姓名'),QStandardItem('分数')]
self.model.appendRow(rootList)
# 设置图标
root.setIcon(QIcon('./images/root.png'))
# 设置根节点的背景颜色
root.setBackground(QBrush(Qt.blue))
rootList[1].setBackground(QBrush(Qt.yellow))
rootList[2].setBackground(QBrush(Qt.red))
# 一级节点
for subject in ['语文','数学','外语','综合']:
itemSubject = QStandardItem(subject)
root.appendRow([itemSubject,QStandardItem(),QStandardItem()])
# 二级节点
for name in ['张三','李四','王五','赵六']:
itemName = QStandardItem(name)
itemName.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEditable | Qt.ItemIsEnabled | Qt.ItemIsUserCheckable)
score = random.random()* 40 + 60
itemScore = QStandardItem(str(score)[:5])
if score >= 90:
itemScore.setBackground(QBrush(Qt.red))
elif 80 <= score < 90:
itemScore.setBackground(QBrush(Qt.darkYellow))
itemSubject.appendRow([QStandardItem(subject),itemName,itemScore])
# 设置树形控件的列的宽度
self.treeView.setColumnWidth(0,150)
# 节点全部展开
self.treeView.expandAll()
# 启用排序
self.treeView.setSortingEnabled(True)
def onClicked(self,index):
text = self.model.data(index)
self.text.appendPlainText(f'触发clicked信号,点击了:"{text}"')
if __name__ =="__main__":
app = QApplication(sys.argv)
demo = QTreeViewDemo()
demo.show()
sys.exit(app.exec())
下面展示另一类用法,展示本机目录结构
from PySide6.QtWidgets import *
from PySide6.QtGui import *
from PySide6.QtCore import *
import sys
import random
import os
os.chdir(os.path.dirname(__file__))
class QTreeViewDemo(QMainWindow):
def __init__(self,parent=None):
super(QTreeViewDemo,self).__init__(parent)
self.setWindowTitle("QTreeView2案例")
self.resize(600,800)
self.text = QPlainTextEdit('用来显示QTreeView2相关信息:')
self.treeView = QTreeView()
self.model = QFileSystemModel()
self.treeView.setModel(self.model)
self.selectModel = QItemSelectionModel()
self.model.setrootPath(QDir.currentPath())
self.treeView.setSelectionModel(self.selectModel)
self.listView = QListView()
self.tableView = QTableView()
self.listView.setModel(self.model)
self.tableView.setModel(self.model)
layoutV = QVBoxLayout(self)
layoutV.addWidget(self.listView)
layoutV.addWidget(self.tableView)
layout = QHBoxLayout(self)
layout.addWidget(self.treeView)
layout.addLayout(layoutV)
widget = QWidget()
self.setCentralWidget(widget)
widget.setLayout(layout)
# 信号与槽
self.treeView.clicked.connect(self.onClicked)
def onClicked(self,index):
self.listView.setrootIndex(index)
self.tableView.setrootIndex(index)
if __name__ =="__main__":
app = QApplication(sys.argv)
demo = QTreeViewDemo()
demo.show()
sys.exit(app.exec())