![编程改变生活:用PySide6/PyQt6创建GUI程序(进阶篇·微课视频版)](https://wfqqreader-1252317822.image.myqcloud.com/cover/921/52841921/b_52841921.jpg)
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所示。
![](https://epubservercos.yuewen.com/59022E/31397649907873106/epubprivate/OEBPS/Images/Figure-P53_94547.jpg?sign=1739253510-DRMsuZzun7R3C2Z0PrPuqOVzKanOYH2Q-0-9d2fa33c9f13ee38417879dd2bb7ec05)
图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所示。
![](https://epubservercos.yuewen.com/59022E/31397649907873106/epubprivate/OEBPS/Images/Figure-P54_94560.jpg?sign=1739253510-G1VqnXmYwJX1FwkOlpVQmZZqJXRDz0ce-0-62bb532ee56b3ca371b06cd673fded76)
图2-2 PySide6中的数据模型
在实际编程中会根据不同的功能选择不同类型的数据模型。PySide6提供的数据模型类的功能见表2-1。
表2-1 PySide6提供的数据模型类
![](https://epubservercos.yuewen.com/59022E/31397649907873106/epubprivate/OEBPS/Images/Figure-T54_133823.jpg?sign=1739253510-6ncWkHAQgdsLtd3H5Sernjy8xxac13aH-0-9f355404a2411c1b54cd3032e28fb4ed)
本章将重点讲述QAbstractItemModel、QStringListModel、QStandardItemModel、QFileSystemModel。
2.1.3 视图控件View
视图控件是用来显示数据模型的显示控件,PySide6提供了多种视图控件,如图2-3所示。
在实际编程中会根据不同的功能选择不同类型的视图控件。PySide6提供的视图控件类的功能见表2-2。
![](https://epubservercos.yuewen.com/59022E/31397649907873106/epubprivate/OEBPS/Images/Figure-P55_94625.jpg?sign=1739253510-yPJlniBOZlcDnnCHX3E612bieAeRCZzA-0-17f7611f53c11637957766e166c8bc95)
图2-3 PySide6中的视图控件
表2-2 PySide6提供的视图控件类
![](https://epubservercos.yuewen.com/59022E/31397649907873106/epubprivate/OEBPS/Images/Figure-T55_133825.jpg?sign=1739253510-Kljt837D9XkW4joyEXXM5jgKXwYikqn2-0-3521af49619882f34984627a1f3eeca0)
本章将重点介绍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所示。
![](https://epubservercos.yuewen.com/59022E/31397649907873106/epubprivate/OEBPS/Images/Figure-P56_94672.jpg?sign=1739253510-vb5fI1a34DcE5QxtQfRbXlExHpm0TZVU-0-35489812f763db7e55c3aae4e52c8073)
图2-4 不同的数据类型
在PySide6中,QModelIndex类的常用方法见表2-3。
表2-3 QModelIndex类的常用方法
![](https://epubservercos.yuewen.com/59022E/31397649907873106/epubprivate/OEBPS/Images/Figure-T56_133827.jpg?sign=1739253510-2XKKdeqdrlPnlvJOBN4XgarEta8fR6nV-0-db28c92c2da9f64d8ad3edd844755811)
2.1.6 抽象数据模型QAbstractItemModel
在PySide6中,QAbstractItemModel类为其他数据模型类的基类,该类提供了数据模型与视图控件的数据接口。QAbstractItemModel类是抽象类,不能直接使用。QAbstractItemModel类的方法被其子类继承。
QAbstractItemModel类的常用方法见表2-4。
表2-4 QAbstractItemModel类的常用方法
![](https://epubservercos.yuewen.com/59022E/31397649907873106/epubprivate/OEBPS/Images/Figure-T56_133829.jpg?sign=1739253510-YXksIefOA6c1V4SVpKkwOD78seBZzMtB-0-c4cdd62e3007fcdf6181a9744d85e667)
续表
![](https://epubservercos.yuewen.com/59022E/31397649907873106/epubprivate/OEBPS/Images/Figure-T58_133833.jpg?sign=1739253510-oSdRbwa04tDRIjUpn5WotH7X3btuOODA-0-939cfdc8a74bbb1ae65055b3f8fb0974)
在PySide6中,Qt.ItemDataRole的枚举值见表2-5。
表2-5 Qt.ItemDataRole的枚举值
![](https://epubservercos.yuewen.com/59022E/31397649907873106/epubprivate/OEBPS/Images/Figure-T58_133835.jpg?sign=1739253510-Lh06xVJP4PjOgTKMbLZ6ghX1z9koWfnY-0-d2b2747921d8ff1cd236f44da00a0efb)
在PySide6中,QAbstractItemModel类的信号也会被其子类继承。QAbstractItemModel类的信号见表2-6。
表2-6 QAbstractItemModel类的信号
![](https://epubservercos.yuewen.com/59022E/31397649907873106/epubprivate/OEBPS/Images/Figure-T59_133837.jpg?sign=1739253510-hLAY8mOx3ryOnwy6M37TmtI31RrcE9rN-0-b143595db857e85b44261d367a24fbc4)
2.1.7 典型应用
前面介绍了模型/视图的基础知识,下面将通过例题来演示如何使用模型/视图来创建控件,并显示数据。
【实例2-1】 创建一个窗口,该窗口包含1个QListView视图控件,该视图控件将数据模型设置为QStringListModel,代码如下:
![](https://epubservercos.yuewen.com/59022E/31397649907873106/epubprivate/OEBPS/Images/Figure-P59_137484.jpg?sign=1739253510-zMbQAXcRknyUGnpQ3zcTGB1algeGczQD-0-a9107251cffd557809fb05478d724e5f)
运行结果如图2-5所示。
![](https://epubservercos.yuewen.com/59022E/31397649907873106/epubprivate/OEBPS/Images/Figure-P60_137495.jpg?sign=1739253510-u4RLtvnFk5juh7HpMVjpjrJXcx9DnDe9-0-3c5ce5879ef210b3e306b7243891aa9f)
图2-5 代码demo1.py的运行结果
注意:与QListWidget、QTableWidget、QTreeWidget创建的控件相同,可以通过双击视图控件的文本来修改内容。