18

I'm creating a program (in Qt Creator 2.8.1, Qt 5.1.1) that basically shows an image, in this case a playing card (along with a few buttons, labels, and a line edit). All widgets are in vertical/horizontal layouts, and the window layout is a grid layout.

I reimplemented the main window's resize event to get the image to resize correctly and ajust the pixmap to it's size - basically, the label expands vertically as much as it can (vertical size policy set to Expand(1)), and then the image is rescaled.

When the window is expanded, everything works fine, and both the label and the image resize correctly. However, I can't shrink the window back: that is, when resizing, I can't get the window to have a smaller height than necessary to include the current label size - neither the label nor the image resize. If I shrink the window horizontally, so that, in order to keep the ratio, the image is shrunk (left-most image), then I can shrink the window vertically. Note that, when resizing the window horizontally, only the image/pixmap is shrunk, not the label.

Here is the code that I'm using to manage the sizes(2):

void MainWindow::resizeEvent(QResizeEvent* event)
{
    QMainWindow::resizeEvent(event);
    //Some code that is not causing the problem - I've checked
    showImage();
}
    
void MainWindow::showImage()
{ 
    int w = ui->imageLabel->width();
    int h = ui->imageLabel->height();

    //Getting image path from file - also not causing the problem
    QPixmap pixmap(":/image/path.png");

    //The image is quite big, so I need to
    // set a scaled pixmap to a w x h window, keeping its aspect ratio
    ui->imageLabel->setPixmap(pixmap.scaled(w,h,Qt::KeepAspectRatio));
    ui->imageLabel->setMask(pixmap.mask());       
}

And here is the arrangement in Qt Designer and when running: Arrangement

So, to recap:

  1. When increasing the windows's height, the label and image grow accordingly, keeping its ratio.
  2. When decreasing the windows's height:
    • If the image doesn't have to change, even if the label does, the window resizes normally.
    • If the image needs to shrink, then the window doesn't resize at all.
  3. When decreasing the windows's width, the window resizes normally
    • If necessary to keep the image ratio, the image(pixmap) shrinks, but the label only shrinks horizontally

What I find weird is that the pixmap prevents the window from resizing vertically, but has no problem in shrinking if the window is resized horizontally.

The question is, as it could only be: any ideas on how to solve this?


(1) Also tried Minimum Expanding, same thing happened. - Also tried resizing the label programatically, but then the other widgets ignore the label's size and don't move, causing overlapping.

(2) Since I am using Qt for pretty much the first time, I can't/don't know how to copy an amount of code that can be copied, compiled and executed, without filling this question with lots of unimportant code.

Note: Feel free to ask for more information that you think may be useful in finding the problem's cause and/or solution.

Community
  • 1
  • 1
Sampaio
  • 337
  • 2
  • 13

2 Answers2

23

For people still looking for a solution, you need to set the minimum size for the QLabel:

ui->imageLabel->setMinimumSize(1, 1);

The solution is pointed out here: https://forum.qt.io/topic/58749/solved-how-to-shrink-qmainwindow-with-a-qlabel-including-an-image/3

mahesh
  • 1,028
  • 10
  • 24
0

First of all, to change the label size, you must select an appropriate size policy for the label like expanding or minimum expanding. Then you must scale the pixmap by keeping its aspect ratio every time it changes, for example in the resizeEvent of the widget that contains your label.

void Widget::resizeEvent(QResizeEvent* event)
{
    QLabel::setPixmap(pix.scaled(this->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation));
}

To keep specific aspect ratio reimplement sizeHint() function, or better yet, use setHeightForWidth(true) and reimplement heightForWidth() function. And don't forget, that your label placed in CentralWidget, but not directly in MainWindow.

Krionix
  • 37
  • 3
  • As stated in the question, I did set the label size policy to expanding and minimum expanding. I also scaled the pixmap everytime it changes (or tried to, in the MainWindow resizeEvent), but got it working properly only for expansion, not contraction. I did not, however, remember/know about the CentralWidget, and as soon as I get home I'll see if I can work with it to solve the problem. Thank you for your input. – Sampaio Jul 24 '14 at 20:19
  • I will explain a little. When you work with QMainWindow in Designer, all controls are placed in the central widget of QMainWindow, see Designer->Form->Show code... You just need to write your own central widget, by subclassing QWidget, reimplement it's heightForWidth() and resizeEvent(). – Krionix Jul 24 '14 at 21:42
  • Uhm, that seems like an interesting idea, and fairly simple, but I'm having problems with one thing: Is there any way to access the label directly in the new widget's resizeEvent? I'm currently doing it with signal/slot connecting, but I'm getting the same result(vertical contraction blocked), so maybe there's a more direct way? – Sampaio Jul 25 '14 at 18:50
  • _Edit:_ I tried passing a pointer to the running main window as an argument in the widget's constructor and storing it: `parent`. However, to access things like `this->parent->ui->imageLabel`, in the widget's resize event, I must set all of these to public in the main window's class(or at least not private). So, again, perhaps there's a more direct way? Thank you for your time – Sampaio Jul 25 '14 at 19:01
  • You still need any help with current problem? – Krionix Jul 28 '14 at 18:37
  • Yes, I do. I have tried following your sugestion, and subclassing QWidget. However, I am having trouble accessing the image label from the new widget's functions. With my current workarounds to accomplish that, _the original problem still exists_ - the window still won't make the image shrink when contracted vertically. – Sampaio Jul 28 '14 at 21:19