QLabel Pixmap in a ScrollArea doesn't zoom in/out correctly



  • Following the ImageViewer example, I created a customized widget to display images. In my case, I need to load an image and fit it in a QLabel Pixmap so it keeps the aspect ratio.
    Then, when the user calls a method (scaleImage) I need the image to zoom in/out according to the scale factor argument. If the image exceeds the size of the QLabel, then the scrollbars appear.

    If I just zoom in or just zoom out several times, it works correctly, but when I, for example, zoom in and then zoom out (or vice versa) it doesn't work well.

    For instance, if I zoom in once then the image becomes bigger, and if I then zoom out, the image doesn't resize. However, if I zoom out again then the image does resize.
    Since I'm resizing the image according to the QLabel's width and height I think these values don't get updated until the method has finished. It's like I'm one step late when switching from zoom in to zoom out.

    Here's some sample simplified code:

    ImageViewer::Viewer(QWidget *parent) : QWidget(parent)
    {
        layout = new QVBoxLayout;
        scrollarea = new QScrollArea;
        label = new QLabel();
    
        setLayout(layout);
        label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
        scrollarea->setWidget(label);
        scrollarea->setWidgetResizable(true);
        layout->addWidget(scrollarea);
    }
    
    ImageViewer::setImage(QImage im)
    {
        QPixmap pm = QPixmap::fromImage(QImage(im));
        label->setPixmap(pm.scaled(label->width(), label->height(), Qt::KeepAspectRatio));
        scalefactor = 1.0;
    }
    
    void ImageViewer::scaleImage(double f)
    {
        scalefactor *= f;
        label->setPixmap(label->pixmap()->scaled(label->pixmap()->width()*scalefactor, label->pixmap()->height()*scalefactor, Qt::KeepAspectRatio));
    }
    

    Any clues?
    Thanks.


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    You should rather keep the original image and then apply the scale factor to it, then update the label content.

    Also, why are you multiplying the scale factor ?



  • @SGaist Thank you for your answer.
    I modified the code so now I have an attribute with the original Pixmap and I use it as you proposed:

    ImageViewer::setImage(QImage im)
    {
        pixmap = QPixmap::fromImage(QImage(im));
        QPixmap pm = pixmap.scaled(pixmap.width() pixmap.height(), Qt::KeepAspectRatio);
        label->setPixmap(pm);
        scalefactor = 1.0;
    }
    
    void ImageWindow::scaleImage(double f)
    {
        scalefactor *= f;
        QPixmap pm = pixmap.scaled(pixmap.width()*scalefactor, pixmap.height()*scalefactor, Qt::KeepAspectRatio);
        label->setPixmap(pm);
    }
    

    This way, I can zoom in/out as I expected, even switchning from in to out. So that partially solves my problem.

    The thing is, I previously used the size of the label since I wanted the image to fit the label's size, keeping the aspect ratio when the image is set. I mean, I first want the image to expand until it reaches the label's width or height. Right now, for instance if I use an image smaller than the label there's a lot of empty space (background). Do you know how to solve this?

    And referring to why I multiply the scale factor, that's because if I want the image to increase 25%, I call scaleImage(1.25), and if I want it to shrink 25% I call scaleImage(0.8), just like in the ImageViewer example.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.