You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

QGraphicsScene调用removeItem()延迟移除项触发段错误

QGraphicsItem调用removeItem后残留、删除触发段错误问题

问题表现

  • 基于C++/Qt的QGraphicsView/QGraphicsScene框架开发简易节点图编辑器
  • 调用scene.removeItem(Item)移除图元后,QGraphicsItem会在场景中残留极短时间才消失
  • 移除图元后立即执行delete删除对象会直接触发段错误;注释掉delete代码时,可观察到图元的局部残缺形态在场景中留存约1秒才完全消失
  • 已尝试的无效修复操作:
    • 移除项前调用prepareGeometryChange()
    • 将QGraphicsView更新模式设置为FullViewportUpdate

问题对应槽函数代码:

void GraphScene::connectionRemoved(QUuid uuid)
{
    //Connections and nodes are stored in QMaps to retrieve them by uuid
    ConnectionGraphicsItem *connectionItem = connections.value(uuid);
    if (connectionItem == nullptr) return;
    removeItem(connectionItem); //Delayed
    //delete connectionItem;
    qDebug() << "con removed" << uuid;
}

问题根因

  1. QGraphicsScene的removeItem操作不会同步触发视图重绘,Qt的界面渲染走事件循环异步调度,默认的脏区标记、重绘触发存在延迟,会导致图元残留
  2. 直接在移除后delete对象,但是事件循环中可能还存在待执行的、访问该图元指针的渲染/事件遍历逻辑,野指针访问就会触发段错误
  3. 存储图元的connections QMap、连接绑定的两端节点锚点都还持有该图元的指针,后续场景遍历、节点重绘时会访问到已从场景移除的无效指针,导致局部残缺绘制、崩溃

修复方案

  • 移除图元前先清理所有外部持有的该图元指针:从connections映射表中删除对应键值对,同时通知连接绑定的两个端点锚点解绑该连接,清空锚点侧保存的连接指针
  • 替换直接delete为connectionItem->deleteLater(),将销毁操作投递到事件循环队列,等当前所有待处理的事件、渲染逻辑执行完成后再销毁对象,避免野指针访问
  • 移除图元前先调用update(connectionItem->boundingRect())标记图元所在区域为脏区,强制触发该区域优先重绘,消除图元残留问题

修复后的参考代码:

void GraphScene::connectionRemoved(QUuid uuid)
{
    // 取出指针的同时从映射表中移除对应条目,避免后续持有野指针
    ConnectionGraphicsItem *connectionItem = connections.take(uuid);
    if (connectionItem == nullptr) return;

    // 解绑两端锚点,清空锚点侧保存的连接指针,方法名根据自身实现调整
    connectionItem->startAnchor()->detachConnection(connectionItem);
    connectionItem->endAnchor()->detachConnection(connectionItem);

    // 标记图元区域待重绘
    update(connectionItem->boundingRect());
    // 从场景移除图元
    removeItem(connectionItem);
    // 延迟删除对象,规避事件循环残留访问导致的段错误
    connectionItem->deleteLater();

    qDebug() << "con removed" << uuid;
}

内容的提问来源于stack exchange,提问作者aelsi2

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 21:36:18