QGraphicsItem movement detection
-
I have QGraphicsTextItem, QGraphicsPixmapItem and QGraphicsRectItem added to QGraphicsScene. My need is whenever these items are moved to new location, I want to know new X and Y positions.
I am aware of flag 'ItemPositionHasChanged' in itemChange() function but it receives new position for every change in coordinates. I need to know position change only after mouse release.
I can think of creating separate subclass for QGraphicsTextItem, QGraphicsPixmapItem, QGraphicsRectItem and reimplement mouseReleaseEvent(). Is there any other better way to detect QGraphicsItem position change ?
-
https://doc.qt.io/qt-5/qgraphicsitem.html#GraphicsItemChange-enum

i think this might work
-
I have QGraphicsTextItem, QGraphicsPixmapItem and QGraphicsRectItem added to QGraphicsScene. My need is whenever these items are moved to new location, I want to know new X and Y positions.
I am aware of flag 'ItemPositionHasChanged' in itemChange() function but it receives new position for every change in coordinates. I need to know position change only after mouse release.
I can think of creating separate subclass for QGraphicsTextItem, QGraphicsPixmapItem, QGraphicsRectItem and reimplement mouseReleaseEvent(). Is there any other better way to detect QGraphicsItem position change ?
@Sridharan
In order not to have to subclass, I don't know but have you checked whetherQGraphicsScene::orQGraphicsView::event()see the mouse release events? -
https://doc.qt.io/qt-5/qgraphicsitem.html#GraphicsItemChange-enum

i think this might work
-
@Sridharan
In order not to have to subclass, I don't know but have you checked whetherQGraphicsScene::orQGraphicsView::event()see the mouse release events? -
I have gone through documentation of QGraphicsScene and QGraphicsView. I think it is not possible
@Sridharan
So unless there is a "move operation complete" signal (end of drag? drop? but not sure there is one) just recognise "mouse release" event and querypos()then. You could compare that against original position to see if moved, or set a flag for "moved" when getitemPositionHasChangedsignal. Then emit your own signal for the end-of-move-with-position. You can probably do this on theevent()method I mentioned in order to override having to subclass each graphics item. -
@Sridharan
So unless there is a "move operation complete" signal (end of drag? drop? but not sure there is one) just recognise "mouse release" event and querypos()then. You could compare that against original position to see if moved, or set a flag for "moved" when getitemPositionHasChangedsignal. Then emit your own signal for the end-of-move-with-position. You can probably do this on theevent()method I mentioned in order to override having to subclass each graphics item. -
To track 'itemPositionHasChanged', shouldn't i need to subclass each graphics item ?
In you last line, you have mentioned about event() method. I didn't understand what to be done here ?
@Sridharan
It does seem thatQGraphicsItem::itemChange(QGraphicsItem::GraphicsItemChange, ...)is onQGraphicsItem, I had thought it was on the scene or view.... So you would indeed need to subclass eachQGraphicsItemsubclass you use to override it. Mind you, once you have changed them all to a subclass once you are done, maybe not too onerous....If you want to avoid having to subclass. Normally when we do this we use
QObject::eventFilter(QObject *object, QEvent *event). But that requires the item monitored to be aQObject, andQGraphicsItems are not. That probably rules out using bool QGraphicsScene::eventFilter(QObject *watched, QEvent *event). So then I suggested you try bool QGraphicsScene::event(QEvent *event) instead to see whether that gives you the the mouse release event to recognise at the scene level instead of the item level? Maybe also something for the "item moved" too? Though you can probably manage without that as you can just look at the item's position. This is for you to try/play with. -
P Pl45m4 referenced this topic on
-
I have QGraphicsTextItem, QGraphicsPixmapItem and QGraphicsRectItem added to QGraphicsScene. My need is whenever these items are moved to new location, I want to know new X and Y positions.
I am aware of flag 'ItemPositionHasChanged' in itemChange() function but it receives new position for every change in coordinates. I need to know position change only after mouse release.
I can think of creating separate subclass for QGraphicsTextItem, QGraphicsPixmapItem, QGraphicsRectItem and reimplement mouseReleaseEvent(). Is there any other better way to detect QGraphicsItem position change ?
@Sridharan , or whoever might come across this and be interested
After all this time I found I needed precisely this for my own purposes. Per https://forum.qt.io/topic/156957/detect-when-qgraphicsitem-dropped/14 I can use QGraphicsItem *QGraphicsScene::mouseGrabberItem() const insideMyGraphicsScene::mouseReleaseEvent()override to detect the end of anyQGraphicsItemdrag-move.void MyGraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { QGraphicsItem *grabbedItem = mouseGrabberItem(); QGraphicsScene::mouseReleaseEvent(event); if (grabbedItem && !mouseGrabberItem()) emit itemMoved(grabbedItem); }The new X/Y position is the position on the item after the move. And this is one function on the
QGraphicsScene, no need to subclass or write code for multipleQGraphicsItemtypes.