Qt5代理模型在完成主模型更新之前更新得太快

  • 本文关键字:更新 模型 代理 Qt5 qt5
  • 更新时间 :
  • 英文 :


我设置了一个主模型(QStandardModel),一个代理模型,它改变了DisplayRole的输出,以及一个单独的表视图显示每个模型。在主模型数据中是一个用户角色,它存储一个指向另一个QObject的指针,代理模型使用该指针来获得所需的显示值。

当该变量所指向的对象被删除时,我遇到了问题。我正在处理删除主模型通过销毁(QObject*)信号。在槽中,我搜索整个模型,查找指向该对象的任何项并删除引用。

该部分本身工作得很好,但我也连接到代理模型的ondatachchanged(…)信号,我在代理模型上调用resizeColumnsToContents()。然后调用代理的data()函数。这里我检查项目是否有指针,如果有,则从对象中获取一些信息以供显示。

所有这些的结果变成:

  1. 对象即将被删除触发销毁(…)信号
  2. 主模型查找使用删除对象的任何项,并调用setData来删除引用
  3. Tableview捕获代理模型的ondatachchanged信号并调整列的大小
  4. 代理模型的数据(…)被调用。它检查主模型中的项是否有对象指针,如果有,则显示对象中的值。

问题是,在步骤4中,主模型中的项目显然还没有被删除;指针地址仍然被存储。但是,指针所引用的对象此时已被删除,从而导致段错误。

我如何修复我的设置,以确保主模型完成删除指针引用代理模型尝试更新之前?

同样,这里是相关部分的伪代码:

// elsewhere
Object *someObject = new QObject();
QModelIndex index = mainModel->index(0,0);
mainModel->setData(index, someObject, ObjectPtrRole);
// do stuff
delete someObject; // Qt is actually doing this, I'm not doing it explicitly
// MainModel
void MainModel::onObjectDestroyed(QObject *obj)
{
  // iterating over all model items
    // if item has pointer to obj
      item->setData(QVariant::fromValue(NULL), ObjectPtrRole));
}
// receives onDataChanged signal
void onProxyModelDataChanged(...)
{
  ui->tblProxyView->reseizeColumnsToContents();
}
void ProxyModel::data(const QModelIndex &index, int role) const
{
  QModelIndex srcIndex = mapToSource(index);
  if(role == Qt::DisplayRole)
  {
    QVariant v = sourceModel()->data(srcIndex, ObjectPtrRole);
    Object *ptr = qvariant_cast<Object*>(v);
    if(ptr != NULL)
      return ptr->getDisplayData();
    else
      return sourceModel->data(srcIndex, role);
  }
}

问题是ptr不是NULL,但引用的对象被删除,在时间ProxyModel::data(…)被调用,所以我结束了一个段错误。

要避免与QObject实例的悬空指针解引用,可以做以下两件事之一:

  1. 使用object->deleteLater -一旦控件返回到事件循环,对象将被删除。这种功能也被称为自动发布池。

  2. 使用QPointer。它会在删除对象时将自身设置为null,因此您可以在使用前检查它。

相关内容

  • 没有找到相关文章

最新更新