fake mouse move events when scrolled programatically
-
On further analysis, I'm not 100 percent sure that the fake mouse events are the cause of my problems. The fact remains that if I comment out the line which moves the scrollbars, the QGraphicsObject moves as I expect, relative to the other QGraphicsObjects. With the movement of the scrollbars in place, the QGraphicsObject moves about 10 times as much as I expect, relative to the other QGraphicsObjects.
Another thing, which I don't think I mentioned, is that dragging the QGraphicsObject off of the scene will cause the bounds of the scene to change. The sequence is
- Drag the QGraphicsObject off of the scene
- mouseMoveEvent is called
- Recalculate the size of the scene and set it.
- adjust the scrollbars manually.
- mouseMoveEvent seems to get triggered additional times (at least one) and reports an inaccurately large mouse movement.
-
On further analysis, I'm not 100 percent sure that the fake mouse events are the cause of my problems. The fact remains that if I comment out the line which moves the scrollbars, the QGraphicsObject moves as I expect, relative to the other QGraphicsObjects. With the movement of the scrollbars in place, the QGraphicsObject moves about 10 times as much as I expect, relative to the other QGraphicsObjects.
Another thing, which I don't think I mentioned, is that dragging the QGraphicsObject off of the scene will cause the bounds of the scene to change. The sequence is
- Drag the QGraphicsObject off of the scene
- mouseMoveEvent is called
- Recalculate the size of the scene and set it.
- adjust the scrollbars manually.
- mouseMoveEvent seems to get triggered additional times (at least one) and reports an inaccurately large mouse movement.
- Small code example showing what goes wrong for people to try? (Minimal to show problem.)
- Some links to where you are getting the code from which describes the problem? (Though maybe you are now saying that turns out not to be relevant?)
- FWIW, it may not have changed but Qt 6.3 is rather old now.
Another thing, which I don't think I mentioned, is that dragging the QGraphicsObject off of the scene will cause the bounds of the scene to change
I would expect this (not the mouse move stuff). Qt expands scene automatically if a
QGraphicsItemis placed outside its current bounds. -
- Small code example showing what goes wrong for people to try? (Minimal to show problem.)
- Some links to where you are getting the code from which describes the problem? (Though maybe you are now saying that turns out not to be relevant?)
- FWIW, it may not have changed but Qt 6.3 is rather old now.
Another thing, which I don't think I mentioned, is that dragging the QGraphicsObject off of the scene will cause the bounds of the scene to change
I would expect this (not the mouse move stuff). Qt expands scene automatically if a
QGraphicsItemis placed outside its current bounds.@JonB If I could reduce the amount of code to something manageable, I would do so. I'm hoping that other people have run into similar situations and have suggestions.
I don't have a choice on what Qt version I use. FYI: we just updated to 6.3. We might be going to a commercial version soon, but we are right now limited to the non-commercial version. I assume 6.3 is the most recent of those, although who knows. It is beyond my control.
The scene doesn't appear to expand automatically for me. I've got a lot of code to calculate how to deal with expanding the scene. From what I found online, it appears that the scene expands automatically if one never calls setSceneRect. Once you set the scene rectangle, you have to deal with the expansion oneself. I'm using qtnodes underneath which calls setSceneRect, so I think I am stuck with figuring it out myself
-
Hi,
6.11.2 is the current latest version available with 6.12 at the corner which will be an LTS.
The current LTS is 6.8. -
This is what AI (for what it is worth) says about the behavior I am seeing. Hopefully someone can tell me if it is correct
"When QAbstractSlider::event() catches a mouse move or slider movement:
-
The slider updates its position, triggering structural viewport shifts.
-
QAbstractScrollArea intercepts viewport-changing instructions and forces an internal repaint/update scheme.
-
To keep the mouse positioning context accurate relative to the underlying QGraphicsScene, Qt synthesizes or forwards corresponding mouse move parameters.
-
Because the viewport() is mapped directly into QGraphicsView, this propagates into QGraphicsView::mouseMoveEvent(QMouseEvent *event) to allow the view to evaluate if it needs to update cursor hover-states, handle interactive dragging/panning behaviors, or translate the action into a QGraphicsSceneMouseEvent for items inside the scene."
#3 seems to be my problem.
-
-
So, I have now verified that moving the scrollbar does generate a simulated mouseMoveEvent, but in the QGraphicsObject and not in the QGraphicsView where I expected it. So here is the sequence of events
- User moves the QGraphicsObject off of the scene.
- The mouse move is detected, the new scene rectangle is calculated, and the scene rectangle is set to the new dimensions.
- Since the user moved the QGraphicsObject off of the scene (and the screen), the scrollbars are adjusted so that the object is still on the screen. If the object was moved above the top of the screen, the vertical scroll bar is adjusted to the top of the scene.
- This triggers a simulated mouseMoveEvent in the QGraphicsObject.
- I can tell this because I my OnNodeMoved method is called. It is connected to the scrollbar's xChange and yChange events.
It looks like the reason that none of the methods to detect the simulated mouse moves worked was because I was looking at the QGraphicsView, not the QGraphicsObject. Unfortunately, the QGraphicsObject is overridden by a third party library. I can debug into it, but I can't override it or change the code.
I'm thinking that I can track the fact that I am programmatically moving the scrollbars and maybe can do something in my OnNodeMoved method, although this happens after Qt has updated the node position and is probably too late.
-
On my graphicsView::mouseMoveEvent, I have the following code
const QPointF nodePositionInSceneCoordinates1 = ngo->scenePos(); verticalScrollBar()->setValue(newSceneTop); const QPointF nodePositionInSceneCoordinates2 = ngo->scenePos();ngo is the QGraphicsObject
The y value for nodePositionInSceneCoordinates1 is -98.8
newSceneTop is -193.8SetValue triggers a QGraphicsObject mouseMoveEvent which causes my OnNodeMoved method to be called.
In OnNodeMoved, I have the following code
const QPointF nodePositionInSceneCoordinates = ngo->scenePos();At this point, nodePositionInSceneCoordinates .y is -232
Why does moving the scrollbars change the scene position of the QGraphicsObject?
I've overwritten QGraphicsScene and I am displaying the scene position of the QGraphicsObject at that point. The value is -494. By the time that I get to my OnNodeMoved method, the value has changed to -786.
There is some QtNodes code inbetween, but nothing that calls setPos to change the position of the node. The first code that executes in NodeGraphicsObject::mouseMoveEvent just calls QGraphicsObject::mouseMoveEvent.
> poweracoustics.exe!cSI_QTN_CALCULATION_NODE::OnNodeMoved() Line 1001 C++ Symbols loaded. poweracoustics.exe!QtPrivate::FunctorCall<QtPrivate::IndexesList<>,QtPrivate::List<>,void,void (__cdecl cSI_QTN_CALCULATION_NODE::*)(void)>::call(void(cSI_QTN_CALCULATION_NODE::*)() f=0x00000009a3316e60, cSI_QTN_CALCULATION_NODE * o=0x000001a4c4b5a5e0, void * * arg=0x00000009a3316fb0) Line 145 C++ Symbols loaded. poweracoustics.exe!QtPrivate::FunctionPointer<void (__cdecl cSI_QTN_CALCULATION_NODE::*)(void)>::call<QtPrivate::List<>,void>(void(cSI_QTN_CALCULATION_NODE::*)() f=0x00000009a3316ee0, cSI_QTN_CALCULATION_NODE * o=0x000001a4c4b5a5e0, void * * arg=0x00000009a3316fb0) Line 183 C++ Symbols loaded. poweracoustics.exe!QtPrivate::QCallableObject<void (__cdecl cSI_QTN_CALCULATION_NODE::*)(void),QtPrivate::List<>,void>::impl(int which=1, QtPrivate::QSlotObjectBase * this_=0x000001a4c4c8f120, QObject * r=0x000001a4c4b5a5e0, void * * a=0x00000009a3316fb0, bool * ret=0x0000000000000000) Line 556 C++ Symbols loaded. Qt6Core.dll!QObject::qt_static_metacall() + 5985 bytes Unknown Non-user code. Cannot find or open the PDB file. Qt6Core.dll!QMetaObject::activate() + 132 bytes Unknown Non-user code. Cannot find or open the PDB file. Qt6Widgets.dll!QGraphicsItemPrivate::setPosHelper() + 205 bytes Unknown Non-user code. Cannot find or open the PDB file. Qt6Widgets.dll!QGraphicsItem::setPos() + 295 bytes Unknown Non-user code. Cannot find or open the PDB file. Qt6Widgets.dll!QGraphicsItem::mouseMoveEvent() + 2958 bytes Unknown Non-user code. Cannot find or open the PDB file. poweracoustics.exe!QtNodes::NodeGraphicsObject::mouseMoveEvent(QGraphicsSceneMouseEvent * event=0x00000009a3318770) Line 306 C++ Symbols loaded. Qt6Widgets.dll!QGraphicsItem::sceneEvent() + 117 bytes Unknown Non-user code. Cannot find or open the PDB file. Qt6Widgets.dll!QGraphicsScene::sendEvent() + 753 bytes Unknown Non-user code. Cannot find or open the PDB file. Qt6Widgets.dll!QGraphicsScene::sendEvent() + 1827 bytes Unknown Non-user code. Cannot find or open the PDB file. Qt6Widgets.dll!QGraphicsScene::mouseMoveEvent() + 144 bytes Unknown Non-user code. Cannot find or open the PDB file. Qt6Widgets.dll!QGraphicsScene::event() + 748 bytes Unknown Non-user code. Cannot find or open the PDB file. poweracoustics.exe!cSI_QTN_GRAPHICS_SCENE::event(QEvent * pEvent=0x00000009a3318770) Line 412 C++ Symbols loaded.The event received by the graphics scene is QEvent::GraphicsSceneMouseMove. The call stack that got us there is
> poweracoustics.exe!cSI_QTN_GRAPHICS_SCENE::event(QEvent * pEvent=0x00000009a3318770) Line 412 C++ Symbols loaded. Qt6Widgets.dll!QApplicationPrivate::notify_helper() + 270 bytes Unknown Non-user code. Cannot find or open the PDB file. Qt6Widgets.dll!QApplication::notify() + 5766 bytes Unknown Non-user code. Cannot find or open the PDB file. Qt6Core.dll!QCoreApplication::notifyInternal2() + 284 bytes Unknown Non-user code. Cannot find or open the PDB file. Qt6Widgets.dll!QGraphicsViewPrivate::mouseMoveEventHandler() + 737 bytes Unknown Non-user code. Cannot find or open the PDB file. Qt6Widgets.dll!QGraphicsView::scrollContentsBy() + 764 bytes Unknown Non-user code. Cannot find or open the PDB file. Qt6Widgets.dll!QAbstractScrollArea::qt_static_metacall() + 183 bytes Unknown Non-user code. Cannot find or open the PDB file. Qt6Core.dll!QObject::qt_static_metacall() + 6091 bytes Unknown Non-user code. Cannot find or open the PDB file. Qt6Core.dll!QMetaObject::activate() + 132 bytes Unknown Non-user code. Cannot find or open the PDB file. Qt6Widgets.dll!QAbstractSlider::setValue() + 295 bytes Unknown Non-user code. Cannot find or open the PDB file. poweracoustics.exe!cSI_QTN_GRAPHICS_VIEW::mouseMoveEvent(QMouseEvent * pEvent=0x00000009a3319bb0) Line 653 C++ Symbols loaded.As you can see, QGraphicsView::scrollContentsBy triggers a mouseMoveEvent even though the mouse isn't moving and the scene position of the QGraphicsObject has not changed, but the view position has.
In addition, QGraphicsObject::yChanged() is triggering even though the scene position of the object hasn't changed. It is just the view position of the object that has changed (due to the movement of the scrollbar).
-
S0 here's the latest
-
When I get a mouseMoveEvent which moves a QGraphicsObject, I calculate the new bounds of the scene and update it if it has changed.
-
If the user user has moved a qgraphicsObject off of the scene, I call QScrollbar::setValue to move the view so that the object is visible.
-
When I call QScrollbar::setValue, QGraphicsView::scrollContentsBy() generates a mouseMoveEvent and calls MouseMoveEventHandler.
4, This causes QGraphicsScene::event to be called. I've overridden the method to display the current scene position of the QGraphicsObject. It still has the scene position it had before I called QScrollBar::setValue.
-
NodeGraphicsObject::mouseMoveEvent is called and that just calls QGraphicsItem::mouseMoveEvent.
-
QGraphicsItem::mouseMoveEvent calls QGraphicsItem::setPos which changes the scene position of the QGraphicsObject.
This seems wrong as the scene position of the QGraphicsObject should not change when the scrollbar positon is moved.
-
QGraphicsItem::setPos calls NodeGraphicsObject::itemChange which results in QGraphicsObject::itemChange being called.
-
This results in the QGraphicsObject::yChanged yChanged signal being triggered and my OnNodeMoved method being called. At this point, the scene position of the object has changed. See 6 above.
According to google AI (for what it is worth), this is the way that it is supposed to work. AI suggests making the object unmovable before scrolling and then turning it back on. Seems like a kludge to me. Seriously, tis can't be the way it is supposed to work.
-
-
Well, I made the change suggested by AI above and it has fixed the problem with the scene position of the QGraphicsObjects changing when the scrollbars are changed. And it fixed a problem where the scrollbars didn't quite end up being in the correct position.
What it didn't fix is the problem that I originally was trying to fix where the dragging of the nodes goes extremely fast when the scene changes