Qt 模型视图框架 前后阅读的好几遍,要不是项目中需要处理一些相对比较多的数据,这部分内容估计不会去急着去理解。
首先来了解下什么是模型和视图框架吧:
一般地:MVC 设计模式包括三个元素:
-
表示数据的模型、
-
表示用户界面的视图
-
定义了用户在界面上操作的控制器
Qt引入InterView框架,把视图和控制器部件结合在一起,使得框架更为简洁。为了灵活处理用户输入,InterView引入了代理(delegatr)。
Qt中模型、视图、代理的三者关系如下:
- 数据发生改变时,模型发出信号通知视图。
- 用户对界面进行操作,视图发出信号。
- 代理发出信号告知模型和视图编辑器目前的状态。
1、模型类
在模型、视图架构中,模型提供了一个标准的接口供视图和委托来访问数据。在Qt中,这个标准的接口使用QAbstractItemModel类来定义。
这里有三个要点:
1、无论数据项是怎样存储在何种底层数据结构中,QAbstractItemModel的子类都会以层次结构来表示数据。
2、视图按照约定来访问模型中的数据项,视图可以使用任何形式将数据显示出来。
3、当模型中的数据发生变化时,模型会通过信号和槽机制告知与其关联的视图。
三种常见的模型:列表、表格、树模型
基本概念:
1、模型索引
为了确保数据的表示与数据的获取相分离,Qt引入了模型索引的概念。视图和委托都使用索引来请求数据项并显示。
2、行和列
如果要获得一个数据项的模型索引,必须指定模型的3个属性:行号、列号、模型索引。
在最基本的形式中,一个模型可以通过把它看做一个简单的表格来访问,每个数据项可以使用行号和列号来定位。
3、父项
在获取数据项的索引时,父项的模型索引可以用QModelIndex()表示。
4、项角色
模型中的数据项可以作为各种角色在其他组件中访问,允许不同的情况提供不同类型的数据。
这些概念一开始接触非常不好理解《QtCreator 快速入门》一书中有实例可以帮助理解:
实例的效果:
实例中是一个简单的树状显示
接着看下代码
#include <QApplication>
#include <QTreeView>
#include <QDebug>
#include <QStandardItemModel>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
// 创建标准项模型
QStandardItemModel model;
// 获取模型的根项(Root Item),根项是不可见的
QStandardItem *parentItem = model.invisibleRootItem();
// 创建标准项item0,并设置显示文本,图标和工具提示
QStandardItem *item0 = new QStandardItem;
item0->setText("A");
QPixmap pixmap0(50,50);
pixmap0.fill("red");
item0->setIcon(QIcon(pixmap0));
item0->setToolTip("indexA");
// 将创建的标准项作为根项的子项
parentItem->appendRow(item0);
// 将创建的标准项作为新的父项
parentItem = item0;
// 创建新的标准项,它将作为item0的子项
QStandardItem *item1 = new QStandardItem;
item1->setText("B");
QPixmap pixmap1(50,50);
pixmap1.fill("blue");
item1->setIcon(QIcon(pixmap1));
item1->setToolTip("indexB");
parentItem->appendRow(item1);
// 创建新的标准项,这里使用了另一种方法来设置文本、图标和工具提示
QStandardItem *item2 = new QStandardItem;
QPixmap pixmap2(50,50);
pixmap2.fill("green");
item2->setData("C", Qt::EditRole);
item2->setData("indexC", Qt::ToolTipRole);
item2->setData(QIcon(pixmap2), Qt::DecorationRole);
parentItem->appendRow(item2);
// 在树视图中显示模型
QTreeView view;
view.setModel(&model);
view.show();
// 获取item0的索引并输出item0的子项数目,然后输出了item1的显示文本和工具提示
QModelIndex indexA = model.index(0, 0, QModelIndex());
qDebug() << "indexA row count: " << model.rowCount(indexA);
QModelIndex indexB = model.index(0, 0, indexA);
qDebug() << "indexB text: " << model.data(indexB, Qt::EditRole).toString();
qDebug() << "indexB toolTip: " << model.data(indexB, Qt::ToolTipRole).toString();
return app.exec();
}
代码的注释很明确:这里用标准模型项类实现的三个项,然后用树状视图显示,并且通过模型索引来访问数据项。
这里我们注释
// parentItem = item0;
并且添加QTableView视图;
QTableView viewtable;
viewtable.setModel(&model);
viewtable.show();
重新构建
这时候弹出两个视图:
到这里,关于父项,行、列、索引、项目角色这些概念应该可以搞清楚了。