Qt模型视图编程.QAbstractItemModel和QAbstractListModel.Index()和paren

Qt Model-View programming. QAbstractItemModel and QAbstractListModel. index() and parent()

本文关键字:Index paren QAbstractListModel Qt 视图 编程 QAbstractItemModel 模型      更新时间:2023-10-16

请帮帮我,我卡住了

我有一个QList的结构,我在QTreeView中以特定的格式显示。我实际上对显示没有问题;我已经重新实现了data(),它工作得很好。

我的数据是"平面的",即每个节点都是根元素。此外,数据不需要从视图中修改,即它是只读的。

我不明白什么是模型索引。如何正确使用它们

目前在data()中,我通过模型 (index.row())返回QList的相应项。这似乎是合法的,这就是data()的作用。

除了data(),我重新实现了rowCount(), columnCount(), flags()headerData()

这是足够的QAbstractListModel,但从QAbstractItemModel子类,我还需要重新实现parent()index()。我不知道在这些函数中需要做什么。如果返回一个空的模型索引(return QModelIndex()),则不会显示任何数据。

我理解MVC的思想:视图能够以许多最合适和最有用的方式显示数据。例如,视图可以按字母顺序或其他方式对数据进行排序,因此显示的行顺序将与应用程序内部组织数据的方式不同。但我不明白如何在我的情况下工作,我的应用程序和Qt的情况下。

视图只是简单地查询我的模型的data()函数的每一行和每一列,因为我的数据没有得到修改,例如排序,视图总是以相同的顺序显示数据(即使我点击标题排序视图)。我可以自己排序列表,但然后我会失去正确的顺序(例如,应用程序想要得到一个项目#3,但在列表被排序后,所需的项目有另一个数字),这看起来不像MVC:当数据的视图改变,数据也改变了。这是不应该的。

以上就是问题所在。代码来了

嗯,我认为没有必要用代码来说明我的问题,因为我已经写了足够多的单词。我实际上有两个问题:我目前从QAbstractListModel子类,但我想从QAbstractItemModel子类。所以我需要写index()parent()。我也不明白排序应该如何工作。

不管怎样,我突然在谷歌上搜索了这个页面。它看起来非常接近我所拥有的(除了编辑:我不需要用视图编辑我的数据,所以我没有实现相应的函数;我还显示图片,而不仅仅是文本(没问题)。我想知道我怎么能做同样的(看那页)与QAbstractItemModel

如果我不清楚,请让我知道。:/

一般来说,如果QAbstractListModelQAbstractTableModel适合您的任务,您应该使用它而不是QAbstractItemModel。你没有说为什么你想从QAbstractItemModel派生。

但你的问题仍然可以回答:

  1. 由于您的数据是平坦的,您应该始终在parent()方法中返回QModelIndex()

  2. index()方法中,如果行和列有效,您应该返回createIndex(row, column),否则返回QModelIndex()。您可以使用createIndex的第3个参数为索引附加额外的数据。

排序是另一个问题。Qt建议将数据模型逻辑和排序逻辑分开。您应该有一个包含主要数据的基本模型。这个模型应该完全不知道任何排序。您应该使用QSortFilterProxyModel对象作为视图的模型,并使用QSortFilterProxyModel::setSourceModel为排序模型设置数据源模型。代理模型将完成所有排序工作,您只需要告诉它该做什么。

@pavel-strakhov:

index()方法中,如果行和列有效,您应该返回createIndex(row, column),否则返回QModelIndex()。您可以使用createIndex的第三个参数为索引附加额外的数据。

这是完全错误的。我已经实现了index(),就像我在上面的答案中被告知的那样,并且得到了一个无限递归的树:每个节点在它的子节点中都有整个树。

我甚至不需要检查行和列是否有效,视图自己利用模型的rowCount()columnCount()方法相当好。

正确做法:

QModelIndex HostModel::index(int row,int column,const QModelIndex &parent) const{
    if(!parent.isValid()) // we should return a valid QModelIndex for root elements (whose parent
        return this->createIndex(row,column); // is invalid) only, because our model is flat
    else
        return QModelIndex();
}

我还问是否我用ModelIndexes做的其他一切都是好的。没有人回答我(即使是有2个赞的答案的作者)。不知道为什么。为什么一个错误的答案得到2个赞,我也不知道。你们让事情变得更糟了。

我认为我在data()中所做的是可以的。但我不确定,但它现在运行良好。

QSortFilterProxyModel()代理请求到我的模型(对应于MVC)排序现在工作正常(好吧,工作得很好)。

p。S.非常感谢@Lol4t0的帮助:他私下在Skype上告诉我应该如何实现index()