一、模型/视图/代理架构简介
1、 应用程序中往往要存储大量的数据,并对它们进行处理,然后可以通过各种形式显示给用户,用户需要时还可以对数据进行编辑。
2、 Qt中的模型/视图架构就是用来实现大量数据的存储、处理及其显示的。
3、 MVC设计模式:
(1)、模型(Model)是应用对象,用来表示数据;
(2)、视图(View)是模型的用户界面,用来显示数据;
(3)、控制(Controller)定义了用户界面对用户输入的反应方式。
4、 Qt的模型/视图架构:
(1)、将MVC设计模式中视图和控制两种组件结合起来,就形成了Qt的模型/视图架构。
(2)、这同样将数据的存储和数据向用户的展示进行了分离,但提供了更为简单的框架。
(3)、相同的数据可以在多个不同的视图上显示。
5、 Qt的模型/视图/代理架构(MVD):
(1)、为了对用户输入进行灵活处理,引入了委托/代理Delegate。
(2)、模型(Model)与数据源进行通信,为架构中的其它组件提供了接口。
(3)、视图(View)从模型中获得模型索引(Model Index,用来表示数据项),进行渲染显示。
(4)、委托/代理(Delegate),可以定制数据项的渲染和编辑方式。用户编辑数据项时,代理使用模型索引直接与模型进行通信。
*模型/视图/代理通过信号和槽进行通信。
*数据源的数据发生改变时,模型发出信号通知视图。
*用户操作界面时,视图发出信号来提供交互信息。
*当编辑数据项时,委托/代理发出信号,告知模型和视图编辑器的状态。
6、 Qt的模型/视图/代理架构,这三个组件的每一个都使用了一个抽象基类来定义,提供了一些通用接口和一些功能的默认实现。
二、模型
1、 所有的模型类都基于QAbstractItemModel类,这个类提供的接口,可以供视图和代理来访问数据。
2、 注意,数据本身并不一定要存储在模型中,可以存储在一个数据结构、独立的类、文件、数据库或其他一些组件中。
3、 Qt提供了一些现成的模型来处理数据:
(1)、QAbstractListModel为基于列表的数据结构提供了一些常见功能的默认实现,可以被子类化提供模型。
(2)、QAbstractTableModel为基于表格的数据结构提供了一些常见功能的默认实现,可以被子类化提供模型。
(3)、QStandardItemModel用于管理复杂的树形结构数据项,每一个数据项可以包含任意的数据。注意没有QAbstractTreeModel类哦!!!
(4)、QStringListModel用来存储一个简单的QString项目列表。
(5)、QFileSystemModel提供了本地文件系统中文件和目录的信息。
(6)、QSqlQueryModel、QSqlTableModel和QSqlRelationTableModel用来访问数据库。
4、 注意,无论数据项是怎样存储在何种底层数据结构中的,QAbstractItemModel子类都会以层次结构来表示数据,视图按照这种约定来访问模型中的数据项。
5、 常见的3种模型分别是列表模型、表格模型、树模型,它们都是层次结构。
6、 模型索引:
(1)、每一块可以通过模型获取的数据都使用一个模型索引来表示,视图和代理都使用这些模型索引来请求数据项并显示。
(2)、模型索引由QModelIndex类提供,它是对一块数据的临时引用,可以用来检索或者修改模型中的数据。因为临时引用,所以不需要存储模型索引。
(3)、如果需要对一块数据进行长时间的引用,则必须使用QPersistentModelIndex创建模型索引。(不经常用)
(4)、模型索引包含一个指针,指向创建它们的模型,使用多个模型时可以避免混淆。
(5)、如果要获得一个数据项的模型索引,则必须指定模型的3个属性:行号、列号、父项的模型索引,
如: QModelIndex index = model->index(row, column, parent);。
7、 行和列:
(1)、列表模型、表格模型中,有一个不存储数据的根项(root item)。
(2)、列表模型和表格模型,都可以看作表格来访问,每个数据项可以使用行号、列号来定位,行号和列号都是从0开始。
(3)、注意,列表模型和表格模型的所有数据项都是以根项(root item)为父项,这些数据项被称为顶层数据项(top level item)。
(4)、获取顶层数据项的模型索引时,父项模型索引可以用QModelIndex()表示,
如: QModelIndex indexA = model->index(0,0,QModelIndex());。
8、 父项:
(1)、树模型中,有一个不存储数据的根项(root item)。
(2)、树模型中,每一个数据项都可能成为其它数据项表格的父项。
(3)、当为数据项请求一个索引时,除了提供行号和列号,还必须提供该数据项的父项模型索引。
(4)、注意,当一个数据项A成为父项时,A的子数据项表格又是从row为0、column为0开始。
9、 项角色:
(1)、通过向模型指定数据项的模型索引以及特定角色,可以获取需要的类型的数据,如: QVariant value = model->data(index, role);。
(2)、数据项可以包含不同角色的数据,这些角色由枚举类型Qt::ItemDataRole定义。
(3)、角色指出了从模型数据项中获取哪种类型的数据,也可以为视图和代理提供提示,告知数据应该怎样展现给用户。
(4)、常用的角色类型:
-> Qt::DisplayRole,数据为QString类型,数据被渲染为文本。
-> Qt::DecorationRole,数据为QColor、QIcon、QPixmap等类型,数据被渲染为图标等装饰。
-> Qt::EditRole,数据为QString类型,数据可以在编辑器中进行编辑。
-> Qt::ToolTipRple,数据为QString类型,数据显示在数据项的工具提示中。
-> Qt::StatusTipRole,数据为QString类型,数据显示在状态栏中。
-> Qt::SizeHintRole,数据为QSize类型,数据项的大小提示,将会应用到视图。
10、 为已存在的数据结构创建新的模型,考虑使用哪种类型的模型?
(1)、若数据结构可以表示为项目列表或者表格,可以子类化QAbstractListModel或QAbstractTableModel。
(2)、若数据结构只能表示具有层次的树结构,可以子类化QAbstractItemModel。(QStandardItemModel管理树结构,不是抽象类)
11、 总结,模型类中就是将各种操作转换为对具体数据源的操作,从而对外提供了一个统一的接口供用户使用。
三、视图简介
1、 所有的视图类都基于QAbstractItemView类。
2、 Qt提供了几种不同类型的视图:
(1)、QListView将模型的数据项显示为一个列表。
(2)、QTableView将模型的数据项显示在一个表格中。
(3)、QTreeView将模型的数据项显示在具有层次的列表(树)中。
3、 视图的作用:
(1)、管理从模型获取的数据的整体布局。
(2)、处理数据项间的导航