如果实际上没有插入,调用 QAbstractItemModel::beginInsertRows() 和 endInsertRows() 会有啥影响?

Posted

技术标签:

【中文标题】如果实际上没有插入,调用 QAbstractItemModel::beginInsertRows() 和 endInsertRows() 会有啥影响?【英文标题】:What is the effect of calling QAbstractItemModel::beginInsertRows() and endInsertRows() if no insertion actually takes place?如果实际上没有插入,调用 QAbstractItemModel::beginInsertRows() 和 endInsertRows() 会有什么影响? 【发布时间】:2015-12-22 16:47:00 【问题描述】:

我正在我的模型中实现拖放行为,该模型派生自 QAbstractItemModel。我的 drop 事件代码 (C++) 如下所示:

beginInsertRows(destination_index, row, row);
destination->AcquireDroppedComponent(component);
endInsertRows();

AcquireDroppedComponent 的调用可能由于多种原因而失败并拒绝删除,在这种情况下,将不会在destination_index 中存储的索引中插入新行。我的问题是,如果发生这种情况,调用 begin/endInsertRows 会导致问题吗?到目前为止,我在 Windows 7 上进行的有限测试没有显示出任何不良行为,但我希望做到彻底,而不是依赖于某个平台的特定行为。我可以事先检查 drop 是否成功,但如果可以的话,我想避免额外的代码。我的问题也适用于 beginRemoveRowsbeginInsertColumns 等其他开始/结束函数。

【问题讨论】:

【参考方案1】:

在不执行您指示的操作的情况下调用这些方法会破坏他们的合同。您的模型的客户将如何应对这种情况基本上是不确定的。

我可以预先检查 drop 是否成功,但如果可以的话,我想避免额外的代码。

“额外”代码是绝对必要的。

我会重构您的代码以分别执行采集和模型更改:

if (destination->acquireDroppedComponent(component)) 
  beginInsertRows(destination_index, row, row);
  destination->insertDroppedComponent(component);
  endInsertRows();

acquireDroppedComponent 会在不修改模型的情况下存储拖放对象的数据,如果成功并且数据可用,则返回true。然后您将调用insertDroppedComponent 来执行模型更改。

【讨论】:

这是一个优雅的解决方案。谢谢。

以上是关于如果实际上没有插入,调用 QAbstractItemModel::beginInsertRows() 和 endInsertRows() 会有啥影响?的主要内容,如果未能解决你的问题,请参考以下文章

如果在循环中插入对象,应该多久调用一次 NSManagedObjectContext 保存?

如果插入智能卡,则 WPF 捕获事件

AVL树插入操作InsertAVL的实现

使用类方法插入 std::map

JSX什么鬼(一起来写一个JSX渲染引擎)

如何判断一个new出来的空对象