c++ - 存储有关 View 中项目的持久信息

标签 c++ qt view model qt5

我有自己的 View ,直接基于 QAbstractItemView。 一般来说,我需要存储一些关于特定模型项目的信息。

所以在我看来,我有一个从 QModelIndex 到描述部分项目的结构的映射。 然后我主要在 View 的 paintEvent 上使用这些数据。

问题是,QModelIndex 不是持久的,它可能会过时。 因此,当从模型中插入或删除行时,一些 QModelIndex 可能会变得无效,我不应该依赖它们。

那么我如何在模型中的项目和我在 View 中使用的一些装饰数据之间建立关系?

QPersistentModelIndex 似乎是处理这些事情的合适工具,但我知道它的性能(我的模型和 View 可能很大)。

QPersistentModelIndex 的另一个问题是它可能不应该用作 map 的键(在我的例子中就是这样),因为它可能(并且将会)改变并使 map 不一致。

我查看了 Qt 的 QTreeView 和 QListView 实现,了解它们如何处理行删除/插入,但它们似乎只是删除了所有数据。

所以在这一点上我看不出有什么简单的方法可以解决我的问题。

最佳答案

您可以安全地使用 QPersistentModelIndex作为 map 或 哈希键。 即使底层 QModelIndex 发生变化,“持久”部分也会确保所有 QPersistentModelIndex在保留其身份的同时保持最新,即 operator ==qHash()返回一致的值。

也就是说,您不应该在 View 中存储有关索引的数据。数据应该由模型存储。 这似乎是它在 Qt 类中的完成方式: View 正在对 QAbstractItemModel::data() 进行大量调用。 .

我认为唯一值得存储在 View 中的数据是“缓存数据”,即:

  • 不是由模型直接提供的
  • 需要根据模型数据进行大量计算
  • 特定于 View

如果这 3 个条件中的任何一个不满足,我个人的偏好是将数据存储在模型中。


编辑

与我最初的回答相反,您不能安全地使用 QPersistentModelIndex作为QMap键。

原因是QMap使用 operator <用于插入和查找数据。

这里的问题是 bool QPersistentModelIndex::operator<(const QPersistentModelIndex &other) const只是 bool QModelIndex::operator<(const QModelIndex &other) const 的代理它按行和列比较索引。 这意味着 QPersistentModelIndex 的排序顺序不持久,当索引在模型中移动时会发生变化。

然而,QMap不知道排序顺序已更改。此时在 QMap<QPersistentModelIndex, T> 中搜索一个值就像在未排序的数组上进行二进制搜索一样糟糕。

请注意,此问题不仅限于 QMap ,它会影响所有基于键顺序的容器,如 std::map .但是,不依赖于排序的容器( QHashstd::unordered_map ……)不受影响。

关于c++ - 存储有关 View 中项目的持久信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27587922/

相关文章:

c++ - 使用 ffmpeg 获取文件信息,目标文件被识别为音频?

c++ - 如何在长 g++ 错误消息上使用 linux less 命令?

c++ - 创建 C++ 注册 QAbstractListModels 后,Qt 在关闭时崩溃

c# - 在ViewModel(MVVM)内部使用 View 方法

c++ - char 数组上的奇怪字符到字符串转换

c++ - QFile::copy() 的进度条?

c++ - QT 程序在 connect() 后崩溃

android - 关于纯用 c++ 编写 android 应用程序(不是混合 java/c++ 应用程序)的良好初学者 Material

android - 如何获取android屏幕的当前 View

macos - Cocoa 文本系统中的幻像字符