我正在使用自定义项类的实例填充QGraphicsScene
(继承QGraphicsPathItem
)。在运行时的某个时刻,我试图从场景中删除一个项(以及它的子项),方法是调用:
delete pItem;
这会自动调用QGraphicsScene::removeItem()
,但是它也会导致类QGraphicsSceneFindItemBspTreeVisitor
在下一次重绘期间崩溃。
发布于 2016-07-19 12:37:46
TL;DR:解决方案是确保在将项目从场景中移除之前,QGraphicsItem::prepareGeometryChange()
被调用。
问题是在项目从现场移除期间,场景内部索引没有正确更新,导致下一次试图绘制场景时崩溃。
因为在我的示例中,我使用了来自QGraphicsPathItem
的自定义子类,所以我只是将对QGraphicsItem::prepareGeometryChange()
的调用放入到它的析构函数中,因为我不是手动从场景中删除项目(通过QGraphicsScene::removeItem()
),而是调用delete pItem;
,这反过来触发了项目的析构函数和removeItem()
。
发布于 2020-03-30 20:41:33
我在使用PySide2时遇到了同样的问题。
禁用BSP索引(如前面提到的这里)确实对我有用,并且很可能是问题的实际解决方案。但是是次优的,因为我正在工作的场景可以变得任意大。在删除项目之前,我还试图调用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)
请注意,这在C++中不会完全相同,因为QGraphicsScene::removeItem
不是一个虚拟方法,因此您可能需要添加自己的方法removeItemSafely
或其他方法。
免责声明:其他方法也适用于我.自从引入这个解决方案以来,我还没有在QGraphicsSceneFindItemBspTreeVisitor::visit
上看到过一次崩溃,但这并不意味着这实际上就是解决方案。使用风险自负。
发布于 2017-09-02 03:12:40
我有这个问题,要解决这个问题真的很痛苦。除了坠机事件之外,我还在屏幕上出现了一些“好吃”的东西。
我在一个自定义的updateGeometry()方法中更改了updateGeometry大小2x,该方法更新项的边界框和形状缓存。
我将赏金矩形初始化为QRectf():
boundingBox = QRectF();
..。然后进行一些处理(并利用这个机会对场景中不需要的对象进行清理)。
最后,将boundingRect的值设置为它的新大小:
boundingBox = polygon.boundingRect();
仅在乞讨中调用prepareGeometryChange()并不能解决这个问题,因为我正在更改它的大小两倍。
解决办法是删除第一个归属。
https://stackoverflow.com/questions/38458830
复制相似问题