Qt 如何从QGraphicscene获取有关addItem或itemChange的通知?
在我的项目中,我使用了一个Qt 如何从QGraphicscene获取有关addItem或itemChange的通知?,qt,notifications,signals,qgraphicsitem,qgraphicsscene,Qt,Notifications,Signals,Qgraphicsitem,Qgraphicsscene,在我的项目中,我使用了一个qgraphicscene,并在整个代码中添加/删除项目 现在我想在添加或删除QGraphicsItem时得到通知。许多Qt类都有通知信号或至少是虚拟函数,这些函数在发生此类更改时会被调用。我试图避免在许多地方添加许多行代码,这不仅麻烦而且不安全(现在或将来忘记插入/删除) 我需要一个能与任何QGraphicsItem一起使用的解决方案 这是一个不起作用的事情列表: 连接到qgraphicscene的信号(如qabstractemmodel::rowsInserted
qgraphicscene
,并在整个代码中添加/删除项目
现在我想在添加或删除QGraphicsItem
时得到通知。许多Qt类都有通知信号或至少是虚拟函数,这些函数在发生此类更改时会被调用。我试图避免在许多地方添加许多行代码,这不仅麻烦而且不安全(现在或将来忘记插入/删除)
我需要一个能与任何QGraphicsItem
一起使用的解决方案
这是一个不起作用的事情列表:
- 连接到
的信号(如qgraphicscene
)->没有信号qabstractemmodel::rowsInserted()
- 继承自
并重载虚拟通知程序函数(如qgraphicscene
)->没有QTabWidget::tabInserted()
- 继承并重载
,自己发送通知(如addItem()
)->QMdiArea::addSubWindow()
不是虚拟的,从addItem
的构造函数调用QGraphicsItems
- 在新添加的
->上安装事件筛选器不知道如何获取新添加的项目,它将是一个QGraphicsItems
,只能安装在其他sceneEventFilter
上QGraphicsItems
- 连接到
->QGraphicsItem
的itemChange
不是信号,重载itemChange()
不是选项QGraphicsItem
- 包装
(将场景作为私有成员)并仅公开函数qgraphicscene
和addItem
->,但该场景中的removietem
仍可以通过qgraphicssitems
函数访问它,因此此解决方案不够安全scene()
如果有一个简单的方法,我只是错过了,请告诉我。除此之外,我非常感谢您的建议。我认为您最好连接到信号
它不会告诉您更改/添加/删除了哪些项目,因为它用于
QGraphicsView
更新显示。但是您应该能够通过使用提供的区域找到答案。我意识到OP的一个要求是不要将该项子类化,但我希望这仍然可以帮助其他最终来到这里的人。Qt正在发送事件来完成此操作,它只需要扩展itemChange
方法以“获得通知”。然后,您可以像这里的示例那样挂接回调方法,或者提供信号,或者您需要的任何东西
这是Python中的模式,但我确信它与C++中的模式相同:
我认为最好的方法就是包装QGraphicscene,并在包装器中提供您自己的
addItem()
函数。遗憾的是,您不能将QGraphicsSitem
子类化,因为它的所有场景更改(包括场景添加/删除)都在sceneEvent(QEvent*事件)中运行
method-它为您的问题提供了一个非常干净和可调的解决方案。@pmr正如我所说的,addItem()
函数不是虚拟的,它是从QGraphicsItem
s的构造函数调用的。所以这不是一个完整的解决方案。我认为pmr的意思是你可以编写一个包含QGraphicsView的类,而不是继承它。该类不会授予对视图的公共访问权限,因此项目的创建者必须调用自己的addItem函数。显然,您无法再通过构造函数提供场景(因为无法从包装器中获取()),您必须更改当前添加到场景中的项目的每一行。@TimMeyer这仍然是不安全的,因为QGraphicsSitems和QGraphicsView都知道它们的场景()-例如用于场景()->removeItem(这个)
-我仍然无法阻止它,或者至少无法得到有关它的通知。
def itemChange(self, change, value):
"""
Runs if this item has the `ItemSendsGeometryChanges` flag set.
This doesn't "accept" any of the changes, it is only to add hooks.
"""
if change == QtWidgets.QGraphicsItem.ItemSceneChange:
# The value for this event is the scene. None means the item was removed.
if value:
self.onAddedtoScene(value)
else:
self.onRemovedFromScene()
return super(SceneNodeBase, self).itemChange(change, value)