如何正确删除QGraphicsItem?

9

如何删除QGraphicsItem?

我使用以下方法从场景中移除项目:

 QGraphicsScene::removeItem(QGraphicsItem * item);

根据此方法的文档:

即,当销毁时,QGraphicsScene将不再删除项目。

因此,我只看到一种方式:

delete item;

也许可以考虑其他的方法?比如对于QWidget,可以设置属性。
setAttribute( Qt::WA_DeleteOnClose );

那会导致对象被删除。QGraphicsItem可能有类似的东西吗?

Item是QGraphics场景中所有项的基类。由于它不是从QObject或QWidget派生的,因此我认为在从场景中删除后正确的删除方式就是调用delete item; - Martin Prazak
item->deleteLater() - ratchet freak
2
@martin_pr 或者你可以使用 QGraphicsObject - thuga
4
@ratchetfreak - 这段话并不复杂,“deleteLater()旨在安全地删除与事件循环相关联的对象,以便在处理完所有事件后进行删除。如果没有事件循环,则不需要使用deleteLater(),也无法使用该函数,因此只需使用delete`即可。 - dtech
1
@martin_pr 是的,但你只会从一个类派生:P - thuga
显示剩余4条评论
2个回答

11

很遗憾,QGraphicsItem 是所有可在 QGraphicsScene 中使用的图形项的基类,并且与 Qt 中大多数"项式"对象一样,未从 QWidgetQObject 派生。此外,它们只能作为另一个 QGraphicsItem 的父项(除了由 QGraphicsScene 拥有)。

从场景中移除一个项后,除非它是另一个 QGraphicsItem 的父项,否则 Qt 期望程序员通过显式调用 delete item; 手动删除它(或使用智能指针来管理该项在被移除后的生命周期)。


1
@rubenvb - 我认为明确地使用智能指针仅仅为了将图形项的生命周期绑定到函数作用域实际上比手动删除它更费力。除非你能提供一个示例,证明智能指针可以管理图形项的整个生命周期,而不仅仅是为了避免在最后手动删除它。 - dtech
1
@rubenvb - 所以你建议为了避免调用delete而存储每个项目的指针是有效的吗?考虑到场景/物品层次结构已经实现了“所有权”模型,尽管不是一种管理生命周期的模型,这完全是多���的。如果出现错误并从智能指针向量中删除仍在场景中的项,则会发生严重问题。而从向量中删除指针与手动删除的工作量相同...你是那些“new/delete有害且错误,不应使用”的福音传道者之一吗? - dtech
2
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - rubenvb
1
不使用智能指针的另一个理由。我个人从来不会真正删除图形项,只是将“已删除”项移动到撤消队列中,由此决定何时需要清除历史步骤。 - dtech
根据Qt文档所述,QGraphicsScene会接管添加到其中的任何项。因此,是的,当场景被删除时,仍附加在场景上的项将被删除。 - Martin Prazak
显示剩余13条评论

0

今天这个问题似乎已经存在很长时间了,也有一些未解决的 bug。

但是好像有一个解决方法,我发现它很有用。在调试、阅读和调查了几个小时之后,我终于在这里找到了答案:

https://forum.qt.io/topic/71316/qgraphicsscenefinditembsptreevisitor-visit-crashes-due-to-an-obsolete-paintevent-after-qgraphicsscene-removeitem/17

关于图形场景的一些其他技巧和提示,请参见此处:https://tech-artists.org/t/qt-properly-removing-qgraphicitems/3063/6


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接