ImageViewer QLabel/QScrollArea top and bottom margins?



  • Hi Everyone. I'm trying to create something like a comic reader using the Qt Image Viewer example as a template.

    I managed to center the image in the middle of the QLabel (or is it QScrollArea? I'm very new to Qt still). My problem is, I want the image to fit the QLabel/QScrollArea automatically when it is opened by the user. Not stretched out to fit the whole screen, but I want the top of the image to meet the top of the GUI screen and the bottom of the image to meet the bottom of the GUI screen.

    For example, this is what I get when opening an image. As you can see, the image is large, so it cuts it off and creates a scroll bar instead.
    0_1538174678834_wrong.PNG

    What I want is the picture zoomed out enough until it meets the top and bottom of the GUI. As you can see in this picture, I manually scrolled out, and where I annotated the image in red is the space that needs to be filled in so the image meets the top and bottom margins perfectly.
    0_1538174757841_want.PNG

    Here is my main constructor where I create the QLabel and QScrollArea:

    Reader::Reader() :
        imageLabel(new QLabel),
        scrollArea(new QScrollArea)
    {
        imageLabel->setBackgroundRole(QPalette::Base);
        imageLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
        imageLabel->setScaledContents(true);
    
        scrollArea->setBackgroundRole(QPalette::Dark);
        scrollArea->setWidget(imageLabel);
        scrollArea->setVisible(false);
        scrollArea->setAlignment(Qt::AlignCenter); // make images appear in center
        setCentralWidget(scrollArea);
    
        createActions();
    
        resize(QGuiApplication::primaryScreen()->availableSize() * 3 / 5);
    }
    

    Here is the function used to set the image when the user navigates back and forth between images (which I stored in a vector when the user selected the files on their computer):

    /* Called when user navigates back and forth between images */
    void Reader::setImage(const QImage& newImage)
    {
        currentImage = newImage;
        imageLabel->setPixmap(QPixmap::fromImage(currentImage));
        scaleFactor = 1.0;
    
        scrollArea->setVisible(true);
        fitToWindowAct->setEnabled(true);
        updateActions();
    
        if (!fitToWindowAct->isChecked()) imageLabel->adjustSize();
    }
    

    Here are my functions for scaling the image and adjusting the scroll bar:

    void Reader::scaleImage(double factor)
    {
        Q_ASSERT(imageLabel->pixmap());
        scaleFactor *= factor;
        imageLabel->resize(scaleFactor * imageLabel->pixmap()->size());
    
        adjustScrollBar(scrollArea->horizontalScrollBar(), factor);
        adjustScrollBar(scrollArea->verticalScrollBar(), factor);
    
        zoomInAct->setEnabled(scaleFactor < 3.0);
        zoomOutAct->setEnabled(scaleFactor > 0.333);
    }
    
    void Reader::adjustScrollBar(QScrollBar *scrollBar, double factor)
    {
        scrollBar->setValue(int(factor * scrollBar->value()
                                + ((factor - 1) * scrollBar->pageStep()/2)));
    }
    

    Please let me know if you need any more code snippets or need me to provide you with any other information, and thanks for your help in advance!


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    Isn't the QScrollArea::widgetResizable property what you are looking for ?



  • @SGaist I tried setting this property to True, and it did not do what I was expecting.

    In addition to fitting the top and bottom of the image to the GUI, it also took the left and right borders and stretched them to fit the GUI as well, distorting the image and making it look wider. I only want the top and bottom to be fit to the GUI. Does this make sense?

    Thanks!


  • Lifetime Qt Champion

    Then you either need to do custom rendering to resize the image the way you want or have the QLabel inside the widget set on the QScrollArea and resize it by hand to set the aspect ratio you need to display your image.



  • @SGaist Could you point me to an example of what you mean by custom rendering?


  • Lifetime Qt Champion

    The Basic Drawing Example shows that. In your case, you'd likely just have to paint your image using the correct scaling information.