Wheel Event zooming QImage

  • Hello,

    I am using the graphics framework where I have a graphicsview subclass that has a graphicsScene and a graphicsItem. In the graphics Item I draw an image in the paint event and that image is shown in the graphicsview, scene, etc. In the wheel event of my graphicsView class I am doing this

    float exp = (-event->delta() / 240.0);
    float factor = powf(1.41, exp);
    scale(factor, 1.0);

    This is used just to zoom in and out in width, having the height stay the same. I'm just having some problems when I zoom out. It works fine but I don't want the image to become smaller in width than the widget that contains my graphics view.
    Does someone know how I can limit the zooming out to the size of the view? In other words I don't want to let the image be any smaller than the rectangle that contains it.
    When zooming in it's fine.
    Any guidance to where I can set this up, I would really appreciate it.


  • The problem with scale() is that it scales relative to the current scale/transformation, so it's difficult to know what the current scale is. To do what you want it is probably easier if you can use absolute scaling, then you can keep track of the scale value where the whole area is filled, and never go below that scale value.
    To do absolute scaling, you can use setTransform() instead of scale(), and create the QTransform using the static fromScale() frunction.

  • @ludde Thanks for the reply! Yes before this I have been trying using transforms but I really can't seem to understand how to use them well. If you can by any chance share some example code I would really appreciate it. In the meantime I'll try however I can what you said.
    Thank you.

  • Hello,

    I've been trying a couple of things without much luck using transforms. First I would like to understand how can I get the scale value to not be able to go under that value. Before doing the verification to see if the scale is going under a specified value, if I do this in the wheel event instead of what is written in above posts:

    float exp = (event->delta() / 240.0);
    float factor = powf(1.41, exp);

    // m_transform is a QTransform defined in the header -- QTranform m_transform; --
    QTransform transform;
    transform = m_transform.fromScale(factor, 1.0);
    m_transform = transform;

    Shouldn't this be identical to what was before?
    before I can zoom in and out smoothly but now it just changes one to one random size and from there it won't move again.
    Could someone please give me a hand on what I'm doing wrong or should be doing?


  • Ok I found why it wasn't doing the same thing as before and it's because I wasn't combining the transforms.

    So doing
    setTransform(transform, true);

    This does the trick. So now my problem is to figure out how to restrict the scale value to not go below the width of the container widget.

  • Combining the transforms will create the same result as before, but also the same problem...
    What you want to do is to calculate the transform yourself, before setting it. Then you can also calculate whether it will scale too much or too little.

    I have some code at home that does something like this, and will try to remember to have a look it it tonight. I think it will help you to better understand what I mean, and how to do it.

  • The very simple code I've used to set an absolute scale instead of a relative scale looks like this:

    @//! Returns the current zoom scale.
    qreal GraphicsView::zoomScale() const
    return transform().m11();

    //! Sets the current zoom scale.
    void GraphicsView::setZoomScale(qreal scale)
    qreal s = qMax(scaleMin, qMin(scaleMax, scale));
    setTransform(QTransform::fromScale(s, s));

    To use it, you need member variables scaleMin and scaleMax, which you can calculate whenever the view is resized. Exactly how to calculate them I don't know, but you should hopefully be able to figure that out. (And of course, to only scale in one dimension, replace one of the s arguments with a 1.)

    Alternatively, you only use scaleMin and scaleMax in the setZoomScale() function, and calculate them there.

  • Thanks Ludde, this is really helpful!

Log in to reply