2.1 模型/视图简介
在PySide6中,基于模型/视图的控件采用了数据与显示相分离的技术。这种技术起源于Smalltalk的设计模式——Model/View/Controller(MVC,模型/视图/控制器),一般应用在显示界面的程序中。与前者不同,PySide6主要采用了Model/View/Delegate(模型/视图/代理)框架,简称为Model/View框架。
2.1.1 Model/View/Delegate框架
在PySide6中,可以使用Model/View/Delegate框架技术来显示、处理不同类型的数据。Model/View/Delegate框架如图2-1所示。
图2-1 Model/View/Delegate框架
在Model/View/Delegate框架中,使用数据模型(Model)从数据源(Data)中读、写数据,使用视图控件(View)显示数据模型中获取的数据。如果用户要编辑数据,则可以使用代理控件(Delegate)编辑或修改数据,并将修改后的数据传递给数据模型(Model),PySide6的视图控件提供了默认的代理控件,例如QTableView中提供了QLineEdit编辑框,所以Model/View/Delegate可以简写为Model/View框架。
在PySide6中,数据模型、视图控件、代理控件通过信号/槽机制进行通信。
2.1.2 数据模型Model
PySide6提供了多种类型的数据模型,如图2-2所示。
图2-2 PySide6中的数据模型
在实际编程中会根据不同的功能选择不同类型的数据模型。PySide6提供的数据模型类的功能见表2-1。
表2-1 PySide6提供的数据模型类
本章将重点讲述QAbstractItemModel、QStringListModel、QStandardItemModel、QFileSystemModel。
2.1.3 视图控件View
视图控件是用来显示数据模型的显示控件,PySide6提供了多种视图控件,如图2-3所示。
在实际编程中会根据不同的功能选择不同类型的视图控件。PySide6提供的视图控件类的功能见表2-2。
图2-3 PySide6中的视图控件
表2-2 PySide6提供的视图控件类
本章将重点介绍QListView、QTableView、QTreeView的应用。
2.1.4 代理控件Delegate
代理控件就是视图控件上为编辑数据提供的临时编辑器。例如当在QTableView控件上编辑一个单元格的数据时,默认提供一个QLineEdit编辑框。代理控件负责从数据模型获取相应的数据,并显示在编辑器里,修改数据后可以将数据保存到数据模型中。
在PySide6中,QAbstractItemDelegate类是所有代理控件类的基类,是一个抽象类,不能直接使用。其子类QStyledItemDelegate类是PySide6中视图控件类的默认代理控件类,默认提供QLineEdit类作为编辑器。如果开发者使用QComboBox、QSpinBox作为代理控件,则要继承QStyledItemDelegate类创建自定义代理控件类。
2.1.5 数据项索引QModelIndex
在数据模型Model中,数据存储的基本单元为item,每个item都对应了唯一的索引值(QModelIndex)。
在PySide6中,使用QModelIndex类表示数据索引,每个数据索引都有3个属性,分别为行、列、父索引。对于一维数据模型只会用到行,例如列表;对于二维数据模型会用到行和列,例如Table;对于三维数据模型会用到行、列、父索引,例如树。这3种数据如图2-4所示。
图2-4 不同的数据类型
在PySide6中,QModelIndex类的常用方法见表2-3。
表2-3 QModelIndex类的常用方法
2.1.6 抽象数据模型QAbstractItemModel
在PySide6中,QAbstractItemModel类为其他数据模型类的基类,该类提供了数据模型与视图控件的数据接口。QAbstractItemModel类是抽象类,不能直接使用。QAbstractItemModel类的方法被其子类继承。
QAbstractItemModel类的常用方法见表2-4。
表2-4 QAbstractItemModel类的常用方法
续表
在PySide6中,Qt.ItemDataRole的枚举值见表2-5。
表2-5 Qt.ItemDataRole的枚举值
在PySide6中,QAbstractItemModel类的信号也会被其子类继承。QAbstractItemModel类的信号见表2-6。
表2-6 QAbstractItemModel类的信号
2.1.7 典型应用
前面介绍了模型/视图的基础知识,下面将通过例题来演示如何使用模型/视图来创建控件,并显示数据。
【实例2-1】 创建一个窗口,该窗口包含1个QListView视图控件,该视图控件将数据模型设置为QStringListModel,代码如下:
运行结果如图2-5所示。
图2-5 代码demo1.py的运行结果
注意:与QListWidget、QTableWidget、QTreeWidget创建的控件相同,可以通过双击视图控件的文本来修改内容。