我使用自定义项类的实例填充QGraphicsScene
(包含QGraphicsPathItem
)。在运行时的某个时刻,我尝试通过调用:
delete pItem;
这会自动调用QGraphicsScene::removeItem()
,但在下一次重绘期间,它也会导致类QGraphicsSceneFindItemBspTreeVisitor
崩溃。
答案 0 :(得分:3)
TL; DR:解决方案是确保{<3}}在 之前被 调用 现场。
问题是在从场景中删除项目期间,场景内部索引未正确更新,导致下次尝试绘制场景时崩溃。
因为在我的情况下,我使用来自QGraphicsPathItem
的自定义子类,我只是将调用QGraphicsItem::prepareGeometryChange()
放入其析构函数中,因为我没有手动从场景中删除项目(通过{{1 }}),但我只是简单地调用QGraphicsScene::removeItem()
,后者会在之后触发项目的析构函数以及delete pItem;
。
答案 1 :(得分:2)
我使用PySide2遇到了同样的问题。
禁用BSP索引(如here所述)确实对我有用,并且很可能是该问题的实际解决方案。但是是次优的,因为我正在处理的场景可以任意变大。我还尝试在删除项目之前致电prepareGeometryChange
,尽管这似乎确实能工作一段时间,但几周后再次出现了该错误。
(到目前为止)对我有用的是在删除项目本身之前手动删除所有子项目...
为此,我要覆盖Python中的QGraphicsScene::removeItem
方法:
class GraphicsScene(QtWidgets.QGraphicsScene):
def removeItem(self, item: QtWidgets.QGraphicsItem) -> None:
for child_item in item.childItems():
super().removeItem(child_item)
super().removeItem(item)
请注意,由于QGraphicsScene::removeItem
不是虚拟方法,因此这在C ++中不太一样,因此您可能必须添加自己的方法removeItemSafely
或其他任何方法。
免责声明:其他方法也对我有效……直到没有奏效为止。自引入此解决方法以来,我还没有在QGraphicsSceneFindItemBspTreeVisitor::visit
中看到崩溃,但这并不意味着这实际上是解决方案。使用风险自负。
答案 2 :(得分:0)
我遇到了这个问题,修复它真的很痛苦。除了崩溃,我还在屏幕上出现“guost”项目。
我在自定义updateGeometry()方法中更改了boundingRect大小2x,该方法更新了项目的边界框和形状缓存。
我正在将边界矩形初始化为QRectf():
boundingBox = QRectF();
...然后进行一些处理(并借此机会对场景中不需要的对象进行一些清理)。
最后将boundingRect的值设置为新的大小:
boundingBox = polygon.boundingRect();
单独调用prepareGeometryChange()并没有解决问题,因为我将它的大小改为两次。
解决方案是删除第一个归因。
答案 3 :(得分:0)
今天这个问题似乎持续了很长时间,而且还存在一些未解决的错误。
但是似乎有一种解决方法,我发现它很有用,经过数小时的调试,阅读和调查,我在这里找到了它:
此处有关Graphics Scene的其他提示和技巧: https://tech-artists.org/t/qt-properly-removing-qgraphicitems/3063/6