QGraphicsview zooming under mouse cursor
-
wrote on 7 Mar 2024, 07:56 last edited by wejgomi 3 Jul 2024, 07:59
Hi,
I am using a basic code for QGraphicsview's mouse wheel event for zooming in & out :
if (event->angleDelta().y() > 0) { scale(1.25, 1.25); } else { scale(0.8, 0.8); }
However that way it zooms by ignoring where the mouse cursor is , but instead where the scene rect is as far as I can understand.
For ex: when you zoom in in GoogleMaps, you will notice that it will also be changing the "sceneRect" and zoom into the area under the mouse cursor.
I have tried changing the scene rect as well based on cursor position but it didn't give the affect that I was looking for. The change in the view was too much and quickly went beyond the canvas before wheel event.
Wanted to ask if in case someone dealt with this before.
Many thanks
-
Hi,
I am using a basic code for QGraphicsview's mouse wheel event for zooming in & out :
if (event->angleDelta().y() > 0) { scale(1.25, 1.25); } else { scale(0.8, 0.8); }
However that way it zooms by ignoring where the mouse cursor is , but instead where the scene rect is as far as I can understand.
For ex: when you zoom in in GoogleMaps, you will notice that it will also be changing the "sceneRect" and zoom into the area under the mouse cursor.
I have tried changing the scene rect as well based on cursor position but it didn't give the affect that I was looking for. The change in the view was too much and quickly went beyond the canvas before wheel event.
Wanted to ask if in case someone dealt with this before.
Many thanks
wrote on 7 Mar 2024, 10:07 last edited by@wejgomi said in QGraphicsview zooming under mouse cursor:
However that way it zooms by ignoring where the mouse cursor is
You need to call
setTransformationAnchor(QGraphicsView::AnchorUnderMouse)
just beforescale()
to have it keep the mouse "anchored".Here is an example I found in old projects of mine, illustrating this. I haven't analyzed it further, but it might give you an idea how I handled it:
/*virtual*/ void MapWindowGraphicsView::wheelEvent(QWheelEvent *event) /*override*/ { // zoom in/out // ensure we deal with with wheel event event->accept(); // set delta scale and the resulting scaling qreal deltaScale = 1.0; deltaScale += (event->angleDelta().y() > 0) ? 0.1 : -0.1; qreal horizontalScale = transform().m11() * deltaScale; qreal verticalScale = transform().m22() * deltaScale; Q_ASSERT(qFuzzyCompare(horizontalScale, verticalScale)); // get the view size QSize viewSize(rect().size()); // get the new scaled scence size QSizeF sceneSize(sceneRect().size()); sceneSize *= horizontalScale; // if it's about the size of the view, or smaller, do a `fitInView()` (limit zoom in) if (sceneSize.width() <= viewSize.width() && sceneSize.height() <= viewSize.height()) { doFitInView(true); return; } // ignore if too large (limit zoom out) if (sceneSize.width() > viewSize.width() * 3 || sceneSize.height() > viewSize.height() * 3) return; doFitInView(false); // do the zoom setTransformationAnchor(QGraphicsView::AnchorUnderMouse); scale(deltaScale, deltaScale); }
-
@wejgomi said in QGraphicsview zooming under mouse cursor:
However that way it zooms by ignoring where the mouse cursor is
You need to call
setTransformationAnchor(QGraphicsView::AnchorUnderMouse)
just beforescale()
to have it keep the mouse "anchored".Here is an example I found in old projects of mine, illustrating this. I haven't analyzed it further, but it might give you an idea how I handled it:
/*virtual*/ void MapWindowGraphicsView::wheelEvent(QWheelEvent *event) /*override*/ { // zoom in/out // ensure we deal with with wheel event event->accept(); // set delta scale and the resulting scaling qreal deltaScale = 1.0; deltaScale += (event->angleDelta().y() > 0) ? 0.1 : -0.1; qreal horizontalScale = transform().m11() * deltaScale; qreal verticalScale = transform().m22() * deltaScale; Q_ASSERT(qFuzzyCompare(horizontalScale, verticalScale)); // get the view size QSize viewSize(rect().size()); // get the new scaled scence size QSizeF sceneSize(sceneRect().size()); sceneSize *= horizontalScale; // if it's about the size of the view, or smaller, do a `fitInView()` (limit zoom in) if (sceneSize.width() <= viewSize.width() && sceneSize.height() <= viewSize.height()) { doFitInView(true); return; } // ignore if too large (limit zoom out) if (sceneSize.width() > viewSize.width() * 3 || sceneSize.height() > viewSize.height() * 3) return; doFitInView(false); // do the zoom setTransformationAnchor(QGraphicsView::AnchorUnderMouse); scale(deltaScale, deltaScale); }
-
Hi,
I am using a basic code for QGraphicsview's mouse wheel event for zooming in & out :
if (event->angleDelta().y() > 0) { scale(1.25, 1.25); } else { scale(0.8, 0.8); }
However that way it zooms by ignoring where the mouse cursor is , but instead where the scene rect is as far as I can understand.
For ex: when you zoom in in GoogleMaps, you will notice that it will also be changing the "sceneRect" and zoom into the area under the mouse cursor.
I have tried changing the scene rect as well based on cursor position but it didn't give the affect that I was looking for. The change in the view was too much and quickly went beyond the canvas before wheel event.
Wanted to ask if in case someone dealt with this before.
Many thanks
wrote on 9 Mar 2024, 08:41 last edited byYou need To set TransformationAnchor before calling the scale function.
setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
void Custome_View::wheelEvent(QWheelEvent *event)
{
setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
double ScaleFactor = 1.15;if(event->delta() > 0) { scale(ScaleFactor,ScaleFactor); } else { scale(1/ScaleFactor,1/ScaleFactor); }
}
-
You need To set TransformationAnchor before calling the scale function.
setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
void Custome_View::wheelEvent(QWheelEvent *event)
{
setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
double ScaleFactor = 1.15;if(event->delta() > 0) { scale(ScaleFactor,ScaleFactor); } else { scale(1/ScaleFactor,1/ScaleFactor); }
}
wrote on 9 Mar 2024, 10:06 last edited by JonB 3 Sept 2024, 10:07@Ketan__Patel__0011 said in QGraphicsview zooming under mouse cursor:
You need To set TransformationAnchor before calling the scale function.
You mean exactly as I wrote above
You need to call
setTransformationAnchor(QGraphicsView::AnchorUnderMouse)
just beforescale()
to have it keep the mouse "anchored".and my code which shows it being used...? :)
-
@Ketan__Patel__0011 said in QGraphicsview zooming under mouse cursor:
You need To set TransformationAnchor before calling the scale function.
You mean exactly as I wrote above
You need to call
setTransformationAnchor(QGraphicsView::AnchorUnderMouse)
just beforescale()
to have it keep the mouse "anchored".and my code which shows it being used...? :)
wrote on 11 Mar 2024, 08:39 last edited by@JonB
Well my code is also is in used and it giving the perfect result and working very well.
2/6