我有自己的 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 架构的语义在文档中没有得到很好的描述。让我尝试制定基本规则。定义:
数据更改:现有项目已更改。
结构变化:添加/删除了行/列。
结构更改间隔:调用
begin[Insert|Delete][Rows|Columns]()
和end[Insert|Delete][Rows|Columns] 之间的间隔()
,以及对beginResetModel()
和endResetModel()
的调用之间。
根据这些定义,以下内容必须成立。遵守这些规则取决于模型和 View 实现。如果一方违反规则,另一方就有未定义的行为。因此,如果您作为模型按照规则行事,您可以期望 View 也遵守这些规则。如果模型违反规则, View 也可以自由违反规则,反之亦然。
dataChanged
信号在存在的行|列上发出,其含义是先前存在的数据已更改。立即在刚添加|删除的行|列上发出它是荒谬的,因为 View 完全知道如果它愿意,它必须读取该数据。在结构更改间隔期间不得发出信号,因为 View 无法对其使用react - 请参阅下面的 #3。只有 模型调用
end[Insert|Delete][Rows|Columns]()
后,行|列才被视为添加|删除。View 在结构更改间隔期间不访问模型。
结构变化只能在结构变化区间内完成。
数据更改只能在结构更改间隔内进行。
所有非持久性索引仅在 单个 间隔 结构更改间隔内有效。
所有非持久性索引在结构更改间隔期间均无效。这是模型在结构更改间隔期间无法访问的简单结果:无论您拥有什么索引,无论如何都是无用的。
一旦结构更改间隔开始,所有非持久索引都会失效。
使用有效索引调用的
[row|column]Count(index)
保持不变,除非在结构更改间隔期间影响具有index
的项目。
invalidated
索引的意思是 View 不能再使用该索引,如果它这样做是未定义的行为。
我的直觉是您的模型没有遵循上面给出的一个或多个规则,因此 View 可能会出现错误行为。这很危险。从技术上讲,该 View 可能会发动核打击或格式化您的硬盘驱动器。不要掉以轻心:)
关于c++ - 我是否需要通知 QTableView QAbstractTableModel 子类中的列数发生了变化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22715861/