目录

1、为什么要使用模型索引

2、确定的接口

3、索引QModelIndex的创建或获取

4、使用索引访问数据

5、一个简单的使用例


以下内容来自QT官方帮助手册,加上了一些自己的理解。

1、为什么要使用模型索引

从名字可以看出,他是模型的索引,只要对模型实体(各种xxxModel的实体)施加这个索引,model就会返回数据集中对应的值,或者通过这个索引修改对应数据集中的值。

类比数组就更好理解了,char buf[8] = {'a', 'b','c','d','e'};  给定索引3,我们就能从数据集合中读出该值为'c',或者任意修改数据集中的第3个值的值。

当然这个例子不太恰当,因为在这个例子中buf这个变量,不仅是数据Data,而且是模型Model。在真正的MVC中,Data的实体是对用户隐藏的,用户只能通过Model来读写Data中的内容,也即只有模型才知道如何获取数据View是不知道,参见我的本系列前面的博文,这样的好处是用户不必关心Data在系统底层的组织方式。举个例子,对于下图所示的树形结构,人直观上看是一目了然的,但是这种数据在内存中的实现方式,却是多种多样的,例如:邻接表法、物化路径法、左右值编码法等等,具体可参考文章《树形结构存储方案对比分析》。

对于这个树,使用不同的管理方法,其数据在内存中的布局方式,编码方式等,是完全不同的。如果让视图View直接读写这些不同类型的编码树,每当需求发生变更时,程序员岂不是得累死。于是QT抽象出一种数据结构,只要是树,统统用树模型(TreeModel)进行中转,这样当内存编码发生改变时,View不必关心,因为View只跟Model打交道,Model会负责把底层的内存编码方式的变化,给统一成一种确定的接口(见下节),提供给View。这样每当需求发生变更时,我们只修改Model类的代码就行了。

 

2、确定的接口

所谓Model与View之间确定的接口,就是被QT已经规定死了的接口,我们继承并写Model类时,必须遵循这种约定,才能使得我们写出的Mdoel送给视图时可以正确显示。QT内置了3种约定的接口,如果你有特殊的需求,可以自定义Model、自定义View,来实现自己的约定。一般来说,内置的这3种约定,已足以满足大多编程需求了。是这样约定的,见下图:

              

  • 对于列表,指定行号就可以唯一确定一个格子;
  • 对于表格,指定行号、列号就可以唯一确定一个格子;
  • 对于树形,指定行号、列号、父索引,才可以唯一确定一个格子;

QT为了使列表、表格、树,三者形式统一而做出的妥协,QT将这三者的item访问方式都规定为:必须提供3个参数:行号、列号、父索引。

只是对于列表模型、表格模型,接口函数已经有了默认参数而已,父索引填QModelIndex的默认构造时,代表最顶层的根节点项Root Item。

直接看官方例子可能会容易,以上图的表格模型为例,看看是如何访问ABC单元格的:

对于表格模型,上述代码的第3参均可不写,因为默认参数就是root节点,也即默认的构造QModelIndex()。

再以上图的树形模型为例,看看是如何访问ABC单元格的:


上述代码中,只要看懂了如何访问根节点的儿子A的儿子B,也即如何访问根节点的孙子B,那就算掌握了QModelIndex的精髓。

3、索引QModelIndex的创建或获取

由前文可知,模型索引QModelIndex只有附着于Model才有意义,因此QModelIndex一般都是从model提供的接口函数中获取。当然,从一个合法的索引中获取其paren父索引、获sibling兄弟索引,也是可以的。

4、使用索引访问数据

读取数据,以下两种方式效果一致。注意data的返回值是QVariant,到底是toString、toInt、toDouble还是to结构体,取决于数据,这里只是以toString为例。

方法(1)
model->index(0,0).data().toString()

方法(2)
model->data(model->index(0,0));

写数据:
model->setData(model->index(0,0), QVariant("programFileTmp"));

5、一个简单的使用例

由前文可见,QModelIndex最重要的作用是,建立起Data中数据的索引与View中数据的索引的映射关系。

例如,用户选中了一个列表视图或者表格视图中的一个元素,这个视图可能是已经做过排序或者部分数据隐藏等操作,那么程序员就可以使用QModelIndex根据视图中用户选中的元素索引,来找到真正的Data中的数据索引。

正因为有了QModelIndex这种映射能力,才使得底层Data的数据组织格式,可以和View呈现的数据组织方式不同。

 

下面来看一个实际的应用场景,如下图所示,当给视图View设置了模型Model以后,并show以后,一旦发生渲染事件,视图就会在后台自动向模型索要数据。

  

视图View向模型Model索要数据,所使用的函数是:

关于该函数中第2个参数,role的作用,可参见该系列我的另一篇博文。

该函数会在View需要重新渲染时,自动向Model索要数据(也即被调用),当然我们也可以主动调用该函数,来获取指定index处的数据。

当用户需要自定义委托编辑数据时,也是需要这个索引才能找到数据。

 

 

 

 

Logo

GitCode 天启AI是一款由 GitCode 团队打造的智能助手,基于先进的LLM(大语言模型)与多智能体 Agent 技术构建,致力于为用户提供高效、智能、多模态的创作与开发支持。它不仅支持自然语言对话,还具备处理文件、生成 PPT、撰写分析报告、开发 Web 应用等多项能力,真正做到“一句话,让 Al帮你完成复杂任务”。

更多推荐