1

Introduction

I am working with the Designer inside the Qt Creator and have a QMainWindow with a QLabel in it. Because the program loads pictures and displays them inside the label i want that the label resizes with a ratio of 1.25 inside setted boundaries when expanding or shrinking the QMainWindow. The label should resize INDEPENDENT, again INDEPENDENT from its content.

What i want:

  • Open the main window for first time:
    width: 640, height: 512
  • Shrinking the main window:
    label shrinks with constant ratio (640/512) till minimum size (320 x 256)
  • Expanding the main window:
    label expands with constant ratio (640/512) till maximum size (1280 x 1024)

1. Approach:

Therefor i...

  • added a QLabel(called imageLabel) inside the centralWidget of the QMainWindow
  • set the centralWidget's layout to grid layout (QGridLayout)
  • sed the following properties to the QLabel:
    • geometry - Can not set the values because of grid layout usages!
    • minimumSize > width: 320, height: 256 (Minimum values)
    • maximumSize > width: 1280, height: 1024 (Maximum values)
    • sizePolicy > Horizontal Policy == Vertical Policy == Expanding

Element structure:

Initial Element structure

This doesn't work because i can not set an initial size in the 'geometry' section. The label does not scale with fixed ratio although it respects minimum and maximum values.

2. Approach:

Following that answer i set an initial pixmap:

QPixmap p;
ui->imageLabel->setPixmap(p.scaled(640, 512, Qt::KeepAspectRatio));

Which didn't change anything.

3. Approach:

I also applied the other answer's class and promoted it to the widget:

Structure after promoting 'AspectRatioPixmapLabel' class

That didn't change anything too.

4. Approach:

I then combined the 2. and 3. approach and set an initial pixmap which...

...didn't change anything.

Here is what it does for the approaches 1. - 4.:

Approaches 1. - 4. - It's all the same

5. Approach

Adding the label of 4. approach into a widget:

5. approach element structure

Well the label doesn't resize at all:

5. approach result

So, how can get the label to have an initial size of 640 x 512 and scale with fixed ratio between 1280 x 1024 and 320 x 256 ?

Community
  • 1
  • 1
goulashsoup
  • 2,639
  • 2
  • 34
  • 60
  • `QLabel::setScaledContents(bool)` ? – Mohammad Kanan Jul 26 '18 at 00:00
  • @MohammadKanan (`ui->imageLabel->setScaledContents(true)`) Doesn't work either. Still like in approaches 1. - 4. – goulashsoup Jul 26 '18 at 00:58
  • If a label is part of a layout its size depends on the size of the widget (or window) to which the layout belongs. So you have to calculate and set the initial size of this widget (or window) instead. – scopchanov Jul 26 '18 at 03:00
  • This may help: [`QSizePolicy::setHeightForWidth`](https://doc.qt.io/Qt-5/qsizepolicy.html#setHeightForWidth) – jonspaceharper Jul 26 '18 at 18:24
  • @scopchanov I really think this is a pretty bad idea. There are spaces and borders between the label and the widget which can change when adding other widgets or changing the spaces, alignment and other things. Adding a calculation for the belonging widget (not the label) would be inconvenient. – goulashsoup Jul 27 '18 at 17:23
  • @goulashsoup, it is not an idea. I've mentioned a fact. – scopchanov Jul 27 '18 at 23:38
  • @eyllanesc I only had time to get back to it just now. Your soultion works. Thx. – goulashsoup Jul 29 '18 at 13:51

1 Answers1

1

A possible solution is to install an eventFilter to the centralwidget so doing the required calculation is set the size.

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->centralWidget->installEventFilter(this);
    ui->imageLabel->setPixmap(QPixmap(":/image.png"));
    ui->imageLabel->setScaledContents(true);
}

bool MainWindow::eventFilter(QObject *watched, QEvent *event)
{
    const float ratio = 1.25;
    if(watched == ui->centralWidget && event->type() == QEvent::Resize
            && ui->centralWidget->width() > 0
            && ui->centralWidget->height() > 0){
        float central_ratio = 1.0*ui->centralWidget->width()/ui->centralWidget->height();        QSize s;
        if(central_ratio > ratio){
            s = QSize(ratio*ui->centralWidget->height(), ui->centralWidget->height());
        }
        else{
            s = QSize(ui->centralWidget->width(), ui->centralWidget->width()/ratio);
        }
        ui->imageLabel->resize(s);
    }
    return QMainWindow::eventFilter(watched, event);
}
eyllanesc
  • 235,170
  • 19
  • 170
  • 241