c++ - 我是否需要通知 QTableView QAbstractTableModel 子类中的列数发生了变化?

标签 c++ qt model-view

我有自己的 QAbstractTableModel 子类。当新数据插入其中时 - 我发出 beginInsertRows/endInsertRows,然后使用正确的索引发出 dataChanged。 rowCount 似乎更改正常,因为我看到滚动条出现并增长,但是...... columnCount 没有。

顺序是这样的:

1) 在将模型插入 tableview 之前填充模型。这种方式 View 捕获适当数量的列。

2) 我先将模型插入 View ,然后用数据填充它。在这种情况下,即使在发出 dataChanged 之后, View 也不会显示任何内容,因为它似乎仍然认为没有列。 (coulmnCount() 返回适当的数量 - 我检查了几次)

从我在 Qt 文档中读到的内容来看,我似乎不需要为大多数模型手动调用 beginInsertColumns ......为什么当模型接收数据时 View 无法选择列数?

P.S.在第二种情况下填充模型后调用:

view->setModel(0);
view->setModel(model);

将列数设置为正确的值,但这很难看...

更新: 我发现发射

emit headerDataChanged(Qt::Horizontal, 0 , columnCount());

确实解决了列问题,但文档说我不应该....... :)

最佳答案

不幸的是,模型- View 架构的语义在文档中没有得到很好的描述。让我尝试制定基本规则。定义:

  1. 数据更改:现有项目已更改。

  2. 结构变化:添加/删除了行/列。

  3. 结构更改间隔:调用 begin[Insert|Delete][Rows|Columns]()end[Insert|Delete][Rows|Columns] 之间的间隔(),以及对 beginResetModel()endResetModel() 的调用之间。

根据这些定义,以下内容必须成立。遵守这些规则取决于模型和 View 实现。如果一方违反规则,另一方就有未定义的行为。因此,如果您作为模型按照规则行事,您可以期望 View 也遵守这些规则。如果模型违反规则, View 也可以自由违反规则,反之亦然。

  1. dataChanged 信号在存在的行|列上发出,其含义是先前存在的数据已更改。立即在刚添加|删除的行|列上发出它是荒谬的,因为 View 完全知道如果它愿意,它必须读取该数据。在结构更改间隔期间不得发出信号,因为 View 无法对其使用react - 请参阅下面的 #3。

  2. 只有 模型调用 end[Insert|Delete][Rows|Columns]() 后,行|列才被视为添加|删除。

  3. View 在结构更改间隔期间不访问模型。

  4. 结构变化只能结构变化区间内完成。

  5. 数据更改只能结构更改间隔内进行。

  6. 所有非持久性索引仅在 单个 间隔 结构更改间隔内有效。

  7. 所有非持久性索引在结构更改间隔期间均无效。这是模型在结构更改间隔期间无法访问的简单结果:无论您拥有什么索引,无论如何都是无用的。

  8. 一旦结构更改间隔开始,所有非持久索引都会失效。

  9. 使用有效索引调用的 [row|column]Count(index) 保持不变,除非在结构更改间隔期间影响具有 index 的项目。

invalidated 索引的意思是 View 不能再使用该索引,如果它这样做是未定义的行为。

我的直觉是您的模型没有遵循上面给出的一个或多个规则,因此 View 可能会出现错误行为。这很危险。从技术上讲,该 View 可能会发动核打击或格式化您的硬盘驱动器。不要掉以轻心:)

关于c++ - 我是否需要通知 QTableView QAbstractTableModel 子类中的列数发生了变化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22715861/

相关文章:

c++ - 为应用程序设置默认光标

c++ - 将多个文件中同一类的函数分开

c++ - 使用自定义 QSortFilterProxyModel 在 QTreeView 上错误的 QModelIndex

c++ - std::sort 用于 vector 在排序自定义对象时引发错误

c# - 为什么 "using System;"不被认为是不好的做法?

qt - QML中的树遍历,检查QModelIndex是否有效

java - Dagger 在 ModelView 中注入(inject) Context

c++ - 在显示不同数据列的两个 View 之间共享一个模型

c++ - 模板函数 roundTo int, float -> 截断

c++ - 多重集 STL 无法识别的查找函数