QAbstractItemModel如何表示树?

时间:2017-01-22 19:05:28

标签: c++ qt tree qtreeview qabstractitemmodel

我仍然很难理解QAbstractItemModel对项目的表示。有两种方法可以返回对我没有任何意义的QModelIndex项。

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

是第一个。传递给这个函数的视图是什么?我索引特定树项目以创建索引?如果是这样,这个功能的重点是什么?为什么不直接返回索引?行和列代表什么?索引实际上是父节点,函数是否根据父节点下面的行数返回特定索引?列是否只是一个无操作?

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

第二,

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

看起来这个方法会返回传递索引的直接父级。我正在处理一个本质上类似于树的数据结构,但存储在一个平面数组中,其中包含有关树深度信息的数组元素,因此直接父节点的父节点总是比其自身深度小1。但在这种情况下,什么得到了createIndex?内部QModelIndex行,列和internalPointer引用了什么?鉴于我正在使用的基于数组的结构,array [0]的父元素应该是什么?

我已经阅读了有关这些主题的Qt示例和文档,似乎无法在理解这些类的工作方式方面取得任何进展。

1 个答案:

答案 0 :(得分:2)

出于某种原因,

QAbstractItemModel被称为“抽象”。它没有定义或强制执行存储模型项的任何特定方式,它完全取决于您,开发人员继承QAbstractItemModel并在子类中实现所需的接口。 QAbstractItemModel强制执行的是视图用于与模型通信的接口。它还有点强制执行的是标准视图如何呈现数据的“心理模型”。

您可以将QAbstractItemModel视为出生在树和桌子家庭中的孩子。想象一棵树:你有一堆物品,每件物品都有自己的子物品,他们也可以有自己的子物品,等等。现在设想一个表:你有一堆项目被排列成一个2D数组,可以按行和列索引。现在假设你有一棵树,所有项目都可以有多个列,因此看起来就像是表格的行。因此,如果你扩展一些已知有子项的树项,你会看到一个表 - 几个子项被排列成几行+每个都有几列。我希望这个心理模型可以帮助理解QAbstractItemModel和看似奇怪的QModelIndex类的界面混乱。

QModelIndex,作为official documentation状态,用于查找模型中的项目。在第一个近似中,索引应该足以使用行,列和父来唯一地标识这种行树模型中的项。实际上QModelIndex允许您执行更多操作:您可以将一些pointer或一些internal id添加到索引中,如果这样可以让您自己的代码更容易识别您自己的模型项您的QAbstractItemModel子类中使用的数据结构。

因此,您询问的方法大致如下:

  1. QAbstractItemModel::index获取所谓模型项的行,列和,并返回与其对应的QModelIndex。稍后,视图可能会使用返回的QModelIndex对象来调用,例如,模型的data方法,以便显示一些实际数据。您可能会问为什么视图不会按行,列和父查询数据?好吧,理论上它可以通过QModelIndex这样做,允许你(特定模型子类的开发者)使用内部指针或内部id这样的技巧。
  2. QAbstractItemModel::parent应该为传递的QModelIndex代表的项目返回父项QModelIndex。如果该项目没有父项,则无效QModelIndex。您现在可能想知道,如果QAbstractItemModel::createIndex获取行,列和指针或ID而不是父QModelIndex,您可以在地球上创建一个QModelIndex来知道其父级吗?答案很简单:QModelIndex返回的QAbstractItemModel::createIndex包含指向已创建它的模型对象的链接;因此,当视图询问其父项的QModelIndex时,该调用将传播到创建QModelIndex的模型,即QAbstractItemModel::parent被调用。现在你的模型应该使用特殊的索引或内部指针或内部id,或者可能是一些疯狂的魔法来识别传入QModelIndex指向的项目的父级。