QGraphicsview zooming under mouse cursor
-
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
@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
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); }
}
-
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); }
}
@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...? :)
@JonB
Well my code is also is in used and it giving the perfect result and working very well.