120-Model/View-树视图QTreeView

树视图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案例

image-20230326231911240

如图所示,本案例创建了上、下两个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())

下面展示另一类用法,展示本机目录结构

image-20230326232120066

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())

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
PyQt5的Model/View是一种用于创建用户界面的框架。它基于MVC(Model-View-Controller)设计模式,提供了一种将数据和界面分离的方法。 Model/View框架中,Model负责管理和提供数据,View负责数据的可视化展示,而两者之间由Controller进行交互。 在PyQt5中,Model通常是QAbstractItemModel类或其子类的实例。它提供了一种标准的接口,用于管理和操作数据。通过Model,我们可以对数据进行添加、删除和修改等操作,并在这些操作之后通知View进行更新。 View则是用户界面上的部件,如QTreeView、QTableView或QListView等。它负责将Model中的数据以视觉化的方式展示给用户,并根据用户的操作与Model进行交互。View会通过信号与槽机制、或直接获取Model的数据来更新界面。 在Model/View框架中,ModelView之间是通过索引(Index)进行连接的。索引是一个由Model提供的标识,用于标记数据的位置和层级关系。View在显示数据时,会根据索引来获取数据的值,并根据需要进行格式化或呈现。 通过Model/View框架,我们可以实现数据和界面的解耦合,通过更改Model中的数据来自动更新界面。同时,Model/View也提供了一些方便的方法和信号,用于处理数据的排序、过滤和选择等操作。 总而言之,PyQt5的Model/View是一种用于创建用户界面的框架,可以通过数据模型和视图来管理和展示数据。它可以使用户界面更加直观、灵活和易于维护。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

士别三日,当挖目相待

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值