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. Expanding image in a QScrollArea
Forum Updated to NodeBB v4.3 + New Features

Expanding image in a QScrollArea

Scheduled Pinned Locked Moved Unsolved General and Desktop
5 Posts 2 Posters 328 Views 2 Watching
  • 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.
  • M Offline
    M Offline
    meator
    wrote last edited by
    #1

    Making pixmaps resizeable in a QLabel is a known issue with several solutions. I'll use the following solution as it seems to be the most promissing: https://stackoverflow.com/a/22618496

    Here's my code: https://github.com/meator/testrepo-qt/tree/stackoverflow-not-fixed-vertically

    Here are the relevant files:

    #pragma once
    
    #include <QLabel>
    
    // https://stackoverflow.com/a/22618496
    class ResizeableLabel : public QLabel
    {
    	Q_OBJECT
    
    public:
    	explicit ResizeableLabel(QWidget * parent = nullptr);
    
    	void set_original_pixmap(const QPixmap & pixmap);
    
    	[[nodiscard]] int heightForWidth(int width) const override;
    	[[nodiscard]] QSize sizeHint() const override;
    
    protected:
    	void resizeEvent(QResizeEvent * event) override;
    
    private:
    	QPixmap original_pixmap;
    };
    
    #include "mainwindow.hpp"
    #include "ui_mainwindow.h"
    
    #include "CustomWidgets.hpp"
    
    ResizeableLabel::ResizeableLabel(QWidget * parent) : QLabel(parent)
    {
    	setMinimumSize(1, 1);
    	setScaledContents(false);
    }
    
    void ResizeableLabel::set_original_pixmap(const QPixmap & pixmap)
    {
    	this->original_pixmap = pixmap.copy();
    }
    
    int ResizeableLabel::heightForWidth(int width) const
    {
    	if (this->original_pixmap.isNull())
    		return height();
    	return ((qreal)this->original_pixmap.height() * width) /
    		   this->original_pixmap.width();
    }
    
    QSize ResizeableLabel::sizeHint() const
    {
    	int w = width();
    	return {w, heightForWidth(w)};
    }
    
    void ResizeableLabel::resizeEvent(QResizeEvent * event)
    {
    	Q_ASSERT(!this->original_pixmap.isNull());
    
    	setPixmap(
    		this->original_pixmap.scaledToWidth(width(), Qt::SmoothTransformation));
    }
    
    MainWindow::MainWindow(QWidget * parent)
    	: QMainWindow(parent), ui(new Ui::MainWindow)
    {
    	ui->setupUi(this);
    	QPixmap pixmap(":/images/Qt_logostrap_CMYK.jpg", "JPG");
    	Q_ASSERT(!pixmap.isNull());
    	ui->image->setPixmap(pixmap);
    	ui->image->set_original_pixmap(pixmap);
    }
    
    MainWindow::~MainWindow()
    {
    	delete ui;
    }
    

    It appears to be resizing well horizontally, but it shrinks weirdly vertically:

    21b571ef-b2ae-4fb1-b479-bb1a178e72c4-image.png

    It should not shrink vertically at all. I put it into a QScrollArea for this reason.

    How can I solve this issue? And is my adaptation of https://stackoverflow.com/a/22618496 optimal or could it be improved?

    Pl45m4P 1 Reply Last reply
    0
    • M meator

      Making pixmaps resizeable in a QLabel is a known issue with several solutions. I'll use the following solution as it seems to be the most promissing: https://stackoverflow.com/a/22618496

      Here's my code: https://github.com/meator/testrepo-qt/tree/stackoverflow-not-fixed-vertically

      Here are the relevant files:

      #pragma once
      
      #include <QLabel>
      
      // https://stackoverflow.com/a/22618496
      class ResizeableLabel : public QLabel
      {
      	Q_OBJECT
      
      public:
      	explicit ResizeableLabel(QWidget * parent = nullptr);
      
      	void set_original_pixmap(const QPixmap & pixmap);
      
      	[[nodiscard]] int heightForWidth(int width) const override;
      	[[nodiscard]] QSize sizeHint() const override;
      
      protected:
      	void resizeEvent(QResizeEvent * event) override;
      
      private:
      	QPixmap original_pixmap;
      };
      
      #include "mainwindow.hpp"
      #include "ui_mainwindow.h"
      
      #include "CustomWidgets.hpp"
      
      ResizeableLabel::ResizeableLabel(QWidget * parent) : QLabel(parent)
      {
      	setMinimumSize(1, 1);
      	setScaledContents(false);
      }
      
      void ResizeableLabel::set_original_pixmap(const QPixmap & pixmap)
      {
      	this->original_pixmap = pixmap.copy();
      }
      
      int ResizeableLabel::heightForWidth(int width) const
      {
      	if (this->original_pixmap.isNull())
      		return height();
      	return ((qreal)this->original_pixmap.height() * width) /
      		   this->original_pixmap.width();
      }
      
      QSize ResizeableLabel::sizeHint() const
      {
      	int w = width();
      	return {w, heightForWidth(w)};
      }
      
      void ResizeableLabel::resizeEvent(QResizeEvent * event)
      {
      	Q_ASSERT(!this->original_pixmap.isNull());
      
      	setPixmap(
      		this->original_pixmap.scaledToWidth(width(), Qt::SmoothTransformation));
      }
      
      MainWindow::MainWindow(QWidget * parent)
      	: QMainWindow(parent), ui(new Ui::MainWindow)
      {
      	ui->setupUi(this);
      	QPixmap pixmap(":/images/Qt_logostrap_CMYK.jpg", "JPG");
      	Q_ASSERT(!pixmap.isNull());
      	ui->image->setPixmap(pixmap);
      	ui->image->set_original_pixmap(pixmap);
      }
      
      MainWindow::~MainWindow()
      {
      	delete ui;
      }
      

      It appears to be resizing well horizontally, but it shrinks weirdly vertically:

      21b571ef-b2ae-4fb1-b479-bb1a178e72c4-image.png

      It should not shrink vertically at all. I put it into a QScrollArea for this reason.

      How can I solve this issue? And is my adaptation of https://stackoverflow.com/a/22618496 optimal or could it be improved?

      Pl45m4P Offline
      Pl45m4P Offline
      Pl45m4
      wrote last edited by
      #2

      @meator

      Hi, check out the Image Viewer Example


      If debugging is the process of removing software bugs, then programming must be the process of putting them in.

      ~E. W. Dijkstra

      M 1 Reply Last reply
      0
      • Pl45m4P Pl45m4

        @meator

        Hi, check out the Image Viewer Example

        M Offline
        M Offline
        meator
        wrote last edited by
        #3

        @Pl45m4 I have read through the Image Viewer Example and I don't think it is of any help here.

        I have:

        1. multiple widgets in the QScrollArea
        2. all widgets must occupy minimum vertical space (it should be "top aligned", I usually do that by adding a vertical spacer as the last element in the layout, but that seems to be causing issues here)
        3. aspect ratio must be preserved
        Pl45m4P 1 Reply Last reply
        0
        • M meator

          @Pl45m4 I have read through the Image Viewer Example and I don't think it is of any help here.

          I have:

          1. multiple widgets in the QScrollArea
          2. all widgets must occupy minimum vertical space (it should be "top aligned", I usually do that by adding a vertical spacer as the last element in the layout, but that seems to be causing issues here)
          3. aspect ratio must be preserved
          Pl45m4P Offline
          Pl45m4P Offline
          Pl45m4
          wrote last edited by Pl45m4
          #4

          @meator said in Expanding image in a QScrollArea:

          multiple widgets in the QScrollArea

          You are using QScrollArea wrong.
          A QScrollArea should not have a layout. Generally you set one widget to it, which you want to scroll. This widget can have a layout with multiple sub-widgets, but not the QScrollArea ifself

          I have read through the Image Viewer Example and I don't think it is of any help here.

          It shows how to use QScrollArea the right way ;-)
          But feel free to do whatever you think is right :)


          If debugging is the process of removing software bugs, then programming must be the process of putting them in.

          ~E. W. Dijkstra

          M 1 Reply Last reply
          2
          • Pl45m4P Pl45m4

            @meator said in Expanding image in a QScrollArea:

            multiple widgets in the QScrollArea

            You are using QScrollArea wrong.
            A QScrollArea should not have a layout. Generally you set one widget to it, which you want to scroll. This widget can have a layout with multiple sub-widgets, but not the QScrollArea ifself

            I have read through the Image Viewer Example and I don't think it is of any help here.

            It shows how to use QScrollArea the right way ;-)
            But feel free to do whatever you think is right :)

            M Offline
            M Offline
            meator
            wrote last edited by
            #5

            @Pl45m4 said in Expanding image in a QScrollArea:

            You are using QScrollArea wrong.
            A QScrollArea should not have a layout. Generally you set one widget to it, which you want to scroll. This widget can have a layout with multiple sub-widgets, but not the QScrollArea ifself

            This should be easy to fix if that's the case. I'll separate my content widget containing text and the image. Will that help me though? In what way is the "right" way better?

            1 Reply Last reply
            0

            • Login

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