Expanding image in a QScrollArea
-
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:
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?
-
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:
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?
-
Hi, check out the Image Viewer Example
@Pl45m4 I have read through the Image Viewer Example and I don't think it is of any help here.
I have:
- multiple widgets in the
QScrollArea
- 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)
- aspect ratio must be preserved
- multiple widgets in the
-
@Pl45m4 I have read through the Image Viewer Example and I don't think it is of any help here.
I have:
- multiple widgets in the
QScrollArea
- 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)
- aspect ratio must be preserved
@meator said in Expanding image in a QScrollArea:
multiple widgets in the QScrollArea
You are using
QScrollArea
wrong.
AQScrollArea
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 theQScrollArea
ifselfI 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 :) - multiple widgets in the
-
@meator said in Expanding image in a QScrollArea:
multiple widgets in the QScrollArea
You are using
QScrollArea
wrong.
AQScrollArea
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 theQScrollArea
ifselfI 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 :)@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 ifselfThis 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?