将界面组件与所编辑的数据分离开,又通过数据源的方式连接起来。Model/View结构:
- 数据(Data):是实际的数据,如数据库的一个数据包或SQL查询结果,内存中的一个StringList,或磁盘文件结构等。
- 模型或数据模型(Model):与实际数据通信,并为视图组件提供该数据接口。从原始数据提取需要的内容,用于视图组件进行显示和编辑。Qt中有预定义的数据模型,如QStringListModel可作为StringList的数据模型,QSqlTableModel可以作为数据库中一个数据表的数据模型。
- 视图或视图组件(View):屏幕上的组件,视图从数据模型中获得每个数据项的模型索引(model index),通过模型索引获取数据。如QListView,QTreeView等。
- 代理(Delegate):定制数据的界面显示和编辑方式,在标准的视图组件中,代理功能显示一个数据,当数据被编辑时,提供一个编辑器,一般是QLineEdit。
模型、视图和代理之间使用信号与槽通信。当源数据发生变化时,数据模型发射信号通知视图组件;当用户在界面上操作数据时,视图组件发射信号表示这些操作信号;当编辑数据时,代理发射信号告知数据模型和视图组件编辑器的状态。
数据模型
所有的基于项数据(item data)的数据模型(Model)都是基于QAbstractItemModel类,这个类定义了视图组件和代理存取数据的接口。
Model类 | 用途 |
---|---|
QStringListModel | 用于处理字符串列表数据的数据模型类 |
QStandardItemModel | 标准的基于项数据的数据模型类,每个项数据可以是任何数据类型 |
QFileSystemModel | 计算机上文件系统的数据模型类 |
QSqlQueryModel | 用于数据库SQL查询结果的数据模型类 |
QSqlTableModel | 用于数据库的一个数据表的数据模型类 |
QSqlRelationalTableModel | 用于关系型数据表的数据模型类 |
QSortFilterProxyModel | 与其他数据模型结合,提供排序和过滤功能的数据模型类 |
Model/View基本结构
数据模型中存储数据的基本单元都是项(item),每个项有一个行号,一个列号,还有一个父项(parent item)。
模型索引
通过数据模型存取的每个数据都有一个模型索引,视图组件和代理通过模型索引来获取数据。
QModelIndex表示模型索引的类。
行号和列号
使用行号和列号只是为了组件之间交互方便的一种规定,通过模型索引的行号和列号就可以存取数据。
QModelIndex indexA = model->index(0, 0, QModelIndex());
QModelIndex indexB = model->index(1, 1, QModelIndex());
QModelIndex indexC = model->index(2, 1, QModelIndex());
父项
QModelIndex indexB = model->index(1, 0, indexA);
项的角色
在为数据模型的一个项设置数据时,可以赋予其不同项的角色的数据。一个项可以有不同角色的数据,对应不同的用途。
void QStandardItem::setData(const QVariant &value, int role= Qt::UserRole + 1)
value 是需要设置的数据,role 是设置数据的角色。一个项可以有不同角色的数据,用于不同的场合。
在获取一个项的数据时也需要指定角色,以获取不同角色的数据:
QVariant QStandardItem::data(int role = Qt::UserRole + 1) const
一般角色:
描述外观和元数据的角色:
视图组件
视图组件在显示数据时,只需调用视图类的setModel()函数,为视图组件设置一个数据模型就可实现视图组件和数据模型之间的关联,在视图组件上的修改将自动保存到关联的数据模型中,一个数据模型可以同时在多个视图组件中显示数据。
视图组件 | 用途 |
---|---|
QListView | 用于显示单列的列表数据,适用于一维数据的操作。 |
QTreeView | 用于显示树状结构数据,适用于树状结构数据的操作。 |
QTableView | 用于显示表格状数据,适用于二维表格型数据的操作。 |
QColumnView | 用于多个QListView显示树状层次结构,树状结构的一层用一个QListView显示。 |
QHeaderView | 提供行表头或列表头的组件。 |
代理
在视图组件上为编辑数据提供编辑器。