Moving a graphics scene in a graphics view on middle click
Unsolved
General and Desktop
-
I am trying to move the scene of a QGraphicsView when clicking the middle mouse button.
So I subclassed QGraphicsView and have overwritten mouseMouseEvent. I have a vector for the movement like this:const auto movement = mapToScene(event->pos() - lastCursorPosition);
Now, my issue is that translate() uses the transformation anchor. Here is what happens with each anchor:
NoAnchor
: Movement is correct, but always starts in the top left. This is unusable for me, since I want to translate the current view.AnchorUnderMouse
: Movement is way too fast. When I move the mouse, I move the anchor, which makes the movement way bigger than I wantedAnchorViewCenter
: Nothing moves, because the center is always centered.
Now, I tried the following things:
- use
NoAnchor
and translate to the current mouse position. No effect since the next translate() moves back to top left - use
AnchorUnderMouse
and translate with 0 / 1 / a fraction of the vector. Movement still way too fast. - set
DragMode
toScrollHandDrag
and send amouseMoveEvent(newEvent)
to the parent, overriding buttons with LeftButton whenever a MiddleButton is received. No resulte since parent seems to be prioritized. - change the position of horizontal and vertical scrollbars instead of using translate, as Qt does with ScrollHandDrag. Not possible, since I cant access the necessary functions.
So, my question is: How do I move the scene of a view when the user drags the mouse with middle button pressed?
If needed, here are the interesting functions:
void GraphicsView::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::MiddleButton) { setCursor(Qt::DragMoveCursor); lastCursorPosition = event->pos(); event->accept(); } QGraphicsView::mousePressEvent(event); } void GraphicsView::mouseMoveEvent(QMouseEvent *event) { if (event->buttons() == Qt::MiddleButton) { // FIXME scene is always moved from the top left corner setTransformationAnchor(AnchorUnderMouse); const auto movement = mapToScene(event->pos() - lastCursorPosition); translate(movement.x(), movement.y()); event->accept(); } else QGraphicsView::mouseMoveEvent(event); } void GraphicsView::mouseReleaseEvent(QMouseEvent *event) { unsetCursor(); QGraphicsView::mouseReleaseEvent(event); }