Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing zoom slider QGraphicsView

I have a need to integrate a zoom slider for a QGraphicsView in Qt 4.x, I have a working implementation that goes something like this:

connect(slider, SIGNAL(valueChanged(int)), customGraphicsView, SLOT(setZoomLevel(int));

In the slot for setZoomLevel I have the following

void CustomView::setZoomLevel(int level)
{
    if(zoomLevel - level < -1){
        setZoomLevel(level - 1);
    }else if(level - zoomLevel < -1){
        setZoomLevel(level + 1);
    }
    if(level < zoomLevel){
        scale(1 - (scaleFactor * (zoomLevel - level)), 1 - (scaleFactor * (zoomLevel - level)));
    }else if (level > zoomLevel){
        scale(1 + (scaleFactor * (level -  zoomLevel)), 1 + (scaleFactor * (level -  zoomLevel)));
    }

    zoomLevel = level;
}

So my issue is stemming from mating a slider which has a value of n to m to represent a zoom level to the scale() function of QGraphicsView, which takes two floating point values to multiply the scene by to get a new size.

So the problem I'm having is, if you take 1 * .9 * 1.1 you do not still get 1 but instead .99, its off slightly because it isn't a correct formula. So my max zoom gets smaller and smaller over time.

The recursive calls are because the slider would sometimes skip values on fast slides, which increased the "error", so I smoothed it out to bandage it a little.

Is there a correct way of handling zooms?

like image 247
John Lotacs Avatar asked Jul 30 '12 14:07

John Lotacs


Video Answer


1 Answers

This took me a while to figure out too. The problem is that QGraphicsView::scale() combines the scale level with the current scale level. Instead try:

setTransform(QTransform::fromScale(sx, sy));

Notice in the documentation that there's an optional second parameter of combine = false. This is good because you don't want to combine the transforms.

If you have other transformations on your QGraphicsView besides scaling, the above suggestion will discard them. In that case you would just use QGraphicsView::transform() to get the current transform, which you can alter however you like, and then use QGraphicsView::setTransform() to set it again.

like image 133
Anthony Avatar answered Oct 20 '22 01:10

Anthony