Qt之Model/View架构
文章目录
- Qt中的Model/View介绍
-
- 什么是model/view
- 什么情况下需要使用Model/View
- Model模型
-
- 模型索引
- 数据项角色item roles
- View视图
- Delegate委托
- Qt中的Model/View使用示例
-
- 示例1:Model/View的基本使用
-
- main.cpp
- MyDataModel
- MyDelegate
- MyHeaderView
- 示例2:Model/View与Sqlite的结合实现百万级数据量的展示
-
- 模型类PagedSqlModel
- 主界面
Qt中的Model/View介绍
什么是model/view
model/view架构是Qt用于分离数据和数据展示的设计模式,来源于MVC架构,即将视图V(view)和控制器C(controller)合并得到的更简洁的Model/View架构。这种架构引入的功能分离使开发者能够更灵活的自定义数据项的展示方式,并提供了一个标准的model接口,使得现有的view视图可以与各种各样的数据源配合使用,多个不同的视图可以显示相同的数据,并且可以在不改变底层数据结构的情况下实现新型的视图。为了实现对用户输入的灵活处理,Qt引入了委托Delegate的概念,它允许自定义数据项的渲染和编辑方式。
模块 | 功能 |
---|---|
Model | 管理数据,为View和Delegate提供了访问数据的标准接口 |
View | 显示数据,从Model获取数据并呈现给用户 |
Delegate | 渲染单元格,并提供编辑窗口 |
model、view、delegate三者之间是通过信和槽通信的,如下图所示:
- model变化时,通知view更新数据;
- view向delegate发射用户和数据项的交互操作的信号;
- 编辑数据时,delegate向model和view发射编辑状态的信号。
什么情况下需要使用Model/View
Model/View这种数据和视图显示分离的架构使得软件结构和功能更加清晰,开发者也能灵活的展示数据项,但是没并不是所有情况下都需要用到这种复杂的设计模式。对于数据量少,数据简单不需要复杂的显示方式,需要快速开发原型时,不需要用到Model/View架构,可以使用Qt提供的封装了Model/View的便利类,如:QListWidget、QTreeWidget 和 QTableWidget。
以下情况推荐使用Model/View架构:
-
多种视图展示同一数据
同一个数据源需要以不同视图展示(如列表、表格、树形)时,Model/View 架构可以轻松实现,修改任意一个视图中的数据,其他视图自动同步更新,切换数据源时,视图代码几乎无需修改。 -
显示大量结构化数据或动态变化的数据时
Model/View架构支持惰性加载和增量更新,它可以避免一次性加载全部数据,节省内存,提升性能,适合处理数据量大或实时数据流。例如示例程序2通过自定义模型分页加载的方式实现百万级数据量的显示。 -
需要支持编辑、排序和过滤时
Model/View 架构天然支持:- 编辑(通过 setData() 和委托)
- 排序(QSortFilterProxyModel)
- 过滤(QSortFilterProxyModel::setFilterRegExp())
见示例程序1
-
需要自定义外观或编辑方式
通过 Delegate(委托),你可以:- 自定义单元格渲染(进度条、图标、按钮)
- 实现复杂编辑器(下拉框、日期选择)
- 添加交互元素(点击、悬停效果)
见示例程序1
Model模型
Model为View和Delegate提供了访问数据的标准接口:
- 提供数据给View;
- 查询某行某列的值;
- 修改数据
- 数据变化时发出信号通知View
这个标准接口由QAbstractItemModel
类定义。QAbstractItemModel
为所有模型类提供了统一的标准接口。它是实现自定义数据模型的基础,允许开发者将各种数据源(数据库、文件、内存结构等)与Qt的视图组件(如 QListView、QTableView、QTreeView)无缝集成。QAbstractItemModel
是一个抽象类,不能直接使用,需要子类继承并实现一些虚函数,Qt提供了一些现成的处理数据项的子模型,如下图所示,对于需要重新实现列表和表格数据结构的模型,Qt提供了更为便利的子模型:QAbstractListModel
和QAbstractTableModel
,这两个类同样是抽象类,不能单独使用,需要继承。