QAbstractItemModel 如何表示树形结构?

4

我仍然很难理解QAbstractItemModel对项的表示。有两种方法返回QModelIndex项,但它们对我来说毫无意义。

QModelIndex QAbstractItemModel::index(int row, int column, const QModelIndex& index)

这是第一句。这个函数接受的参数是什么视图?我索引特定的树项来创建一个索引吗?如果是,那么这个函数有什么意义呢?为什么不直接返回索引? row 和 column 代表什么?索引实际上是父节点吗,该函数基于父节点下面的行数返回具体的索引?在这里column只是无操作吗?

当传递的row参数被使用时,如果有的话,row 0是指索引/父节点本身还是它下面的第一项?

其次,

QModelIndex QAbstractItemModel::parent(const QModelIndex& index) const

似乎这个方法将返回传递索引的直接父级。我正在处理一种本质上类似树形结构但存储在平面数组中的数据结构,其中数组元素包含有关树深度的信息,因此直接父级始终具有比自己深度小1的父级。但是在这种情况下,createIndex接收到了什么?内部QModelIndex行、列和内部指针是什么意思?考虑到我使用的基于数组的结构,array [0]的父级应该是什么?
我已经阅读了Qt这些主题的示例和文档,但似乎无法理解这些类如何工作。
1个回答

4

QAbstractItemModel被称为“抽象”的原因是它不定义或强制执行存储模型项的任何特定方式,完全由您作为开发人员通过子类化QAbstractItemModel并在其子类中实现所需接口来决定。 QAbstractItemModel强制执行的是视图用于与模型通信的接口。它还有点强制性地表达了标准视图如何呈现数据的“心理模型”。

您可以将QAbstractItemModel看作是树和表的家族中诞生的孩子。想象一棵树:您有许多项目,每个项目都可以有自己的子项目,它们也可以有自己的子项目,依此类推。现在想象一张表:您有许多项目,这些项目被排列成2D数组,可以按行和列进行索引。现在想象您有一棵树,其中所有项目都可以具有多个列,因此看起来像表的行。因此,如果您展开某个已知具有子项的树项,则会看到一个表格-几个子项排列成几行+每个子项都有几列。我希望这种心理模型可以帮助理解QAbstractItemModel的界面,以及看似奇怪的QModelIndex类。

QModelIndex,正如官方文档所述,用于定位模型中的项目。在第一次近似中,索引应具有行、列和父项,以唯一标识树形模型中的项目。实际上,QModelIndex允许您做更多的事情:如果这使得您自己的代码更容易地识别QAbstractItemModel子类中使用的自己的数据结构中的模型项,则可以将一些pointerinternal id放入索引中。

因此,你问到的方法大致如下:

  1. QAbstractItemModel::index接受模型项的行、列和父项,并返回相应的QModelIndex。稍后视图可能会使用返回的QModelIndex对象调用您的模型中的data方法,以获取要显示的实际数据。您可能会问,为什么视图不只是通过行、列和父项查询数据?理论上可以这样做,但通过QModelIndex这样做允许您作为特定模型子类的开发人员使用内部指针或内部ID等技巧。
  2. QAbstractItemModel::parent应该返回表示传入QModelIndex所代表的项的父项的QModelIndex,或者如果该项没有父项,则为无效QModelIndex。您可能会想现在如何创建一个QModelIndex,使其知道其父项,如果QAbstractItemModel::createIndex只接受行、列和指针或ID,而不接受父项QModelIndex?答案很简单:QAbstractItemModel::createIndex返回的QModelIndex包含一个链接到创建它的模型对象;因此,当视图请求其父项的QModelIndex时,该调用被传播到创建该QModelIndex的模型,即现在调用了QAbstractItemModel::parent。现在应该使用您的模型使用特殊索引、内部指针、内部ID或甚至某些疯狂的魔法来标识由传入的QModelIndex指向的项的父项。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接