QAbstractItemModel如何表示树?

QAbstractItemModel如何表示树?

问题描述:

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

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

是第一个。传递给这个函数的视图是什么?我索引特定树项目以创建索引?如果是这样,该功能有什么意义?为什么不只是返回索引?行和列代表什么?索引实际上是一个父节点,该函数根据该父级下的行数返回特定索引?列在这里只是一个没有操作?

当使用在实际的行参数,如果有的话,不排0参考索引/父节点本身,或在它下面的第一项?

其次,

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

看起来这方法将返回通过指数的直接父。我正在处理一种固有的树状数据结构,但它存储在一个平面数组中,其中的数组元素包含有关树深度的信息,所以直接父级总是会有一个深度小于其深度的父级。但是在这种情况下获得createIndex的是什么?内部QModelIndex行,列和内部指针是指什么?鉴于我使用的基于数组的结构,array [0]的父类应该是什么?

我已经读了Qt的实例和文档关于这些主题已经,并且似乎无法让理解这些类是如何工作的任何进展。

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

你能想到的QAbstractItemModel作为出生在家庭树和一张桌子的孩子。想象一下树:你有一堆物品,每个物品可以有自己的子物品,他们也可以有他们的子物品等等。现在想象一张桌子:你有一堆物品被排列成一个可以按行和列索引的二维数组。现在想象一下,你有一棵树的所有项目可以有多个列,因此看起来像表中的行。所以,如果你说扩大一些已知有子项目的树项目,你会看到一个表格 - 几个子项目排成几行,每个子项目有几列。我希望这个心智模型可以帮助理解QAbstractItemModel和看起来很奇怪的QModelIndex类别的混淆界面。

QModelIndex,因为official documentation状态用于定位模型中的项目。在第一个近似值中,索引应该足够让一行,一列和一个父项在此行树模型中唯一标识该项目。在现实中QModelIndex允许你做更多的:你可以把一些pointer或一些internal id进入指数,如果这使得它更容易为自己的代码在你QAbstractItemModel子类使用您自己的数据结构中识别模型项目。

因此,你问的方法做大致有以下几种:

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