Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QGraphicsview zooming under mouse cursor
Forum Updated to NodeBB v4.3 + New Features

QGraphicsview zooming under mouse cursor

Scheduled Pinned Locked Moved Unsolved General and Desktop
6 Posts 3 Posters 1.3k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • W Offline
    W Offline
    wejgomi
    wrote on 7 Mar 2024, 07:56 last edited by wejgomi 3 Jul 2024, 07:59
    #1

    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

    J K 2 Replies Last reply 7 Mar 2024, 10:07
    0
    • W wejgomi
      7 Mar 2024, 07:56

      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

      J Offline
      J Offline
      JonB
      wrote on 7 Mar 2024, 10:07 last edited by
      #2

      @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 before scale() 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);
      }
      
      W 1 Reply Last reply 8 Mar 2024, 11:48
      2
      • J JonB
        7 Mar 2024, 10:07

        @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 before scale() 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);
        }
        
        W Offline
        W Offline
        wejgomi
        wrote on 8 Mar 2024, 11:48 last edited by
        #3

        @JonB Many thanks for the answer.

        1 Reply Last reply
        0
        • W wejgomi
          7 Mar 2024, 07:56

          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

          K Offline
          K Offline
          Ketan__Patel__0011
          wrote on 9 Mar 2024, 08:41 last edited by
          #4

          @wejgomi

          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);
          }
          

          }

          J 1 Reply Last reply 9 Mar 2024, 10:06
          0
          • K Ketan__Patel__0011
            9 Mar 2024, 08:41

            @wejgomi

            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);
            }
            

            }

            J Offline
            J Offline
            JonB
            wrote on 9 Mar 2024, 10:06 last edited by JonB 3 Sept 2024, 10:07
            #5

            @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 before scale() to have it keep the mouse "anchored".

            and my code which shows it being used...? :)

            K 1 Reply Last reply 11 Mar 2024, 08:39
            0
            • J JonB
              9 Mar 2024, 10:06

              @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 before scale() to have it keep the mouse "anchored".

              and my code which shows it being used...? :)

              K Offline
              K Offline
              Ketan__Patel__0011
              wrote on 11 Mar 2024, 08:39 last edited by
              #6

              @JonB
              Well my code is also is in used and it giving the perfect result and working very well.

              1 Reply Last reply
              0

              2/6

              7 Mar 2024, 10:07

              topic:navigator.unread, 4
              • Login

              • Login or register to search.
              2 out of 6
              • First post
                2/6
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved