Qt模型视图编程.QAbstractItemModel和QAbstractListModel.Index()和paren
Qt Model-View programming. QAbstractItemModel and QAbstractListModel. index() and parent()
请帮帮我,我卡住了
我有一个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
。
一般来说,如果QAbstractListModel
或QAbstractTableModel
适合您的任务,您应该使用它而不是QAbstractItemModel
。你没有说为什么你想从QAbstractItemModel
派生。
但你的问题仍然可以回答:
-
由于您的数据是平坦的,您应该始终在
parent()
方法中返回QModelIndex()
。 -
在
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()
。
- 在提升multi_index容器中,是否定义了"default index"?
- DrawIndexedInstanced 具有不同的 Index Count per Instance (Directx
- 有没有办法使用递归函数找到数组中最小值的 INDEX?C++
- OpenGL VBO Indexing ( How to compute Index Array)
- "Warning: Comma within array index expression"但逗号分隔函数参数
- 如何根据排序索引的向量对 std::index 集进行排序?
- 在一行代码中理解 index++
- 为什么打印 c 样式字符串的'address of index n'会导致子字符串的输出
- 使用 std::get 访问 std::variant<index>
- 代码中的"vector<<int>vector>&index"是什么意思?
- CStringArray::GetAt(int index) 返回一个 const. 为什么?
- 如何配置 Doxygen 以在"Class Index"中包含类的类型定义?
- QList::operator[]中的断言失败<T>:QJoysticks 中的"index out of range"
- Array.at(index) over Array[index]
- 在 Lua 中加载 C++ 模块时'Attempt to index a string value'错误
- 为什么 c++ 向量没有"delete by index"?
- Amazon aws-cpp-sdk Index Faces 给出段错误
- 如何在C++中使用MongoDB GeoSpatial Index
- QList<T>::operator[]: "index out of range" 中的断言失败
- Qt模型视图编程.QAbstractItemModel和QAbstractListModel.Index()和paren