如何为已经存在的没有复制的树状数据结构实现QAbstractItemModel?

问题描述 投票:0回答:1

阅读了QAbstractItemModelQAbstractItemModel的文档和示例后,我仍然对如何正确实现QModelIndex的模型感到困惑。

因为我想为existing分层数据结构提供模型,所以我避免使用QModelIndexQTreeView以及与数据复制和同步有关的问题。但是,我无法实现工作项模型(问题太多,发布代码没有用)。

[读取QTreeView后,似乎很清楚QTreeWidget QTreeWidget,但仅依靠模型告诉给定索引的父级。因此,如果不定义至少另一个用于存储这种关系的帮助程序类,似乎不可能为现有数据结构提供抽象树模型。但是,我仍然无法正确实现模型。

假设数据结构就是这个简单的结构:

QStandardItemModel

其中QStandardItemModel是最顶层的,它类似于一棵树。this answer中显示的树可能如下所示:

QModelIndex

应如何实现QModelIndex子类以访问现有数据而不进行复制?

qt qtreeview qabstractitemmodel
1个回答
0
投票

这是我的解决方案。

首先,我对does not contain hierarchical information无法存储父子关系的最初猜测是正确的。实际上,方法struct Property { QString name; QString value; }; struct Node { QString name; QVector<Property> properties; }; struct Track { int length; QString channel; }; struct Model { QVector<Node> nodes; QVector<Track> tracks; }; 只是调用Model,而实现父方法的任务留给了模型类。当基础模型是适当的树时,指向树节点的指针可以存储在QTreeView类中,但是在我的情况下,我们正在处理“虚拟”树,并且这种关系不可用。因此,我们被迫引入某种额外的存储空间,以便能够分辨出我们在树中的位置。如果QTreeView本机支持具有指向父索引的指针,则可以更轻松地解决此问题。但是由于Model ├─Nodes │ ├─Node "node1" │ │ └─Properties │ │ ├─Property property1 = value1 │ │ └─Property property2 = value2 │ └─Node "node2" │ └─Properties │ └─Property property1 = someValue └─Tracks ├─Track 1, ... ├─Track 2, ... └─Track 3, ... 是一个值类,所以我们不能为父类添加pointer,而是必须将所有父级索引存储在QAbstractItemModel类中,也许Qt开发人员有一些不错的方法这样做。因此,我在QAbstractItemModel的内部指针字段中存储了QModelIndex。有一些需要注意的事情,例如避免分配过多的此类索引,还记得在不再需要这些索引时记住释放内存(我们在这里不能使用QObject层次结构)。当模型是读写模型时,可能还要解决其他问题,但是在这种情况下,我正在处理只读模型。

我的实现如下。方法QModelIndex::parentQAbstractItemModel::parent定义此特定的虚拟树。其他方法可以抽象到可以重用的类中。

QModelIndex

实现:

QModelIndex
© www.soinside.com 2019 - 2024. All rights reserved.