Moving a graphics scene in a graphics view on middle click
-
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
NoAnchorand translate to the current mouse position. No effect since the next translate() moves back to top left - use
AnchorUnderMouseand translate with 0 / 1 / a fraction of the vector. Movement still way too fast. - set
DragModetoScrollHandDragand 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); }