简述
模型视图框架有三大基本概念:模型、视图、代理。下面要介绍的是其中的模型。
基本概念
在模型/视图框架中,模型为视图和代理获取数据提供了标准的接口。这个标准接口由QAbstractItemModel定义,QAbstractItemModel是所有模型类的基类。无论数据项目在底层数据结构中是如何存储的,QAbstractItemModel都会以包含项目表的层级结构来表示这些数据。 视图会按照这种接口来获取模型中的数据项目。但是,它们向用户呈现此信息的方式不受限制。
![](https://i-blog.csdnimg.cn/blog_migrate/9d4c9ef371a0a83313311841de81e699.png)
模型索引
为了确保数据的表示方式与访问方式分开,引入了模型索引的概念。可以通过模型获得的每条信息都由模型索引表示。视图和代理使用这些索引来请求用于显示的数据。
只有模型需要知道如何获取数据,并且可以相当普遍地定义模型管理的数据类型。模型索引包含指向创建它们的模型的指针,这可以防止在使用多个模型时产生混淆。
QAbstractItemModel *model = index.model();
模型索引提供了对信息的临时引用,可用于模型检索或修改数据。由于模型可能会不时重组其内部结构,因此模型索引可能会变得无效,因此不应进行存储。如果需要长期参考一条信息,则必须创建一个永久模型索引。QModelIndex提供临时的模型索引,QPersistentModelIndex提供永久模型索引。
为了获取一个数据项目所对应的模型索引,必须为模型指定三个属性:行号,列号以及父代的模型索引。下面将会详细地描述与解释这些属性。
行和列
可以将模型作为一个简单的表进行访问,在该表中,按行号和列号定位数据项。我们可以通过在模型中指定给定项目的行号和列号来检索有关任何给定项目的信息,并且我们收到代表该项目的索引。
QModelIndex index = model->index(row, column, ...);
为简单的单层数据结构(如列表和表格)提供接口的模型不需要提供任何其他信息,但是,如上述代码所示,在获取模型索引时,我们需要提供更多信息。
![](https://i-blog.csdnimg.cn/blog_migrate/f5d7aa0b3324d5ec9a42bd49b6b75c24.png)
该图显示了表格模型的表示形式,其中每个项目都由一对行号和列号定位。通过将相关的行号和列号传递给模型,我们获得了引用数据项的模型索引。
QModelIndex indexA = model->index(0, 0, QModelIndex());
QModelIndex indexB = model->index(1, 1, QModelIndex());
QModelIndex indexC = model->index(2, 1, QModelIndex());
始终通过将QModelIndex()指定为其父项来引用模型中的顶级项。下一节将对此进行讨论。
项目的父代
当在表格视图或列表视图中使用数据时,行号和列号便可以唯一地映射到视图项目。但是,诸如树视图的结构,除了行号和列好之外,还要求提供父代项目。
当请求一个模型项目的索引的时候,我们必须提供该项目父代的信息。在模型外部,引用项目的唯一方法是通过模型索引,因此还必须提供父代模型索引:
QModelIndex index = model->index(row, column, parent);
![](https://i-blog.csdnimg.cn/blog_migrate/c32a29376d0333eacff43ffb4d146402.png)
该图显示了树模型的表示形式,其中每个项目均由父代,行号和列号引用。项目"A"和"C"在模型中表示为顶级同级:
QModelIndex indexA = model->index(0, 0, QModelIndex());
QModelIndex indexC = model->index(2, 1, QModelIndex());
项目"A"具有多个子代。使用以下代码获得项目"B"的模型索引:
QModelIndex indexB = model->index(1, 0, indexA);
项目角色
模型中的项目可以为其他组件执行各种角色(即数据种类),从而可以为不同的情况提供不同种类的数据。例如,Qt :: DisplayRole用于访问可以在视图中显示为文本的字符串。通常,项目包含许多不同角色的数据,标准角色由Qt :: ItemDataRole定义。我们可以通过向模型传递与该项目相对应的模型索引,并通过指定一个角色来获取我们所需数据的类型:
QVariant value = model->data(index, role);
![](https://i-blog.csdnimg.cn/blog_migrate/57a08c5b6d949cbcf0fb06527d8f9417.png)
该角色向模型指示要引用的数据类型。视图可以以不同的方式显示角色,因此为每个角色提供适当的信息很重要。创建新模型部分将更详细地介绍角色的一些特定用法。
Qt::ItemDataRole中定义的标准角色已经覆盖了项目数据的绝大多数用法。通过给每一个角色提供合适的项目数据,模型可以向视图和代理提供有关如何将项目呈现给用户的提示。不同类型的视图可以根据需要自由解释或忽略此信息。也可以为特定于应用程序的目的定义其他角色。
总结
- 模型索引以独立于任何基础数据结构的方式向视图和代理提供了有关模型所提供项目位置的信息。
- 项目数据通过其行号和列号以及其父项的模型索引来引用。
- 模型索引是由模型根据其他组件(例如视图和代理)的请求构造的。
- 如果使用index()请求索引时为父项指定了有效的模型索引,则返回的索引将引用模型中该父项之下的项。获得的索引指向该项目的子项。
- 如果使用index()请求索引时为父项指定了无效的模型索引,则返回的索引将引用模型中的顶级项。
- 角色用来区分与项目关联的不同类型的数据。
引用
[1] Qt 助手