Resize QLayout to the minimum after widget size changes
Asked Answered
B

4

39

I've got a QGridLayout with a few widgets in it. The important ones are 2 labels, which I use for drawing images to the screen. Well, if the user wants, he can change the resolution of the incoming images, thus, forcing the Labels to resize.

Let's assume the initial size of the label is 320x240. The user changes the VideoMode to 640x480, the label, and the entire GUI resizes perfectly. But when the user switches back to 320x240, the label shrinks, but the Layout/Window does NOT.

I've played around with sizePolicies and sizeHints, and resize(0,0), but nothing did the trick.

Here are some screenshots to clarify the problem:

Here, everything is okay

still, 640 x 480 resizes perfectly

but here, the layout is too big.

Brooklet answered 20/2, 2013 at 13:7 Comment(0)
B
75

You need to set the size constraint of the layout holding all your widgets to "SetFixedSize". Although the name doesn't sound like it will work, it ensures that your layout will only use the space it needs. You will not have the problem like you do in your second screenshot.

Example:

mainLayout.setSizeConstraint(QLayout::SetFixedSize);
Bendy answered 30/1, 2014 at 14:13 Comment(7)
Thank you! This saved me another couple of hours searching and debugging caused by this horrible naming. Why does SetFixedSize imply "automatic resize to minimum size" which is semantically NOT a fixed size because the minimum size depends on the (potentially dynamic) sizes of the widget's contents? Is there ANY explanation for this?Selfcongratulation
The name does not make much sense, and its been a while since I worked with Qt, so I don't recall how I found this out. But this problem bugged me for a while. Glad it helped youBendy
This appears to work for everything except for QScrollArea widgets. Do you know a solution for that?Gupta
nvm, I found I can set it to ignored and let size policy of child widgets dictate sizing (see last response here: qtcentre.org/threads/7593-QScrollArea-and-resizing)Gupta
nvm nvm, it doesn't expand anymore to fit child contents. Maybe I need to ask a separate question...Gupta
Nice, this was such a long search to get this right!Hooknose
Interestingly, setSizeConstraint did not solve the problem for me in PySide6, see https://mcmap.net/q/409319/-how-to-auto-resize-a-pyside6-app-to-the-minimum-size-when-decreasing-a-pixmap/880783. QTimer.singleShot(0, self.adjustSize) was the solution there.Providing
C
11

QLayout::setSizeConstraint(QLayout::SetFixedSize) solves this problem well when you prefer keeping your widget's size fixed at all times — that is, if you'd like it to always be fixed to its "packed" size (which may still vary as the child widgets change size).

That is what the "fixed" means there: "fixed" to the correct size, even as the latter varies. (In Qt terms, what I'm calling the "packed" size is simply the widget's sizeHint.)

But a constraint may be too strong a solution in some instances. In particular, if you apply it to a top-level window, then the user will not be free to resize the window.

If you don't like that, you can instead perform the "set size to sizeHint" operation instantaneously each time it's needed, rather than imposing it as an unrelenting constraint. The way to do that is to call QWidget::adjustSize().

Note that if the container whose children are changing size is not the top-level window, then adjustSize() may have to be called recursively on the container and its parents. (In my case, I had to do that, anyway. I also tried the size-constraint scheme, and found that applying the constraint at only the topmost level was successful in compacting all levels. I haven't enough knowledge of Qt to comment usefully on these observations, so I merely share them.)

Coons answered 26/11, 2015 at 5:5 Comment(0)
C
2

You need to store the original size of your widget parent window before applying any changes to the layout and restore it when the user switches back to the original.

Notice that you need to work with the widget parent window size and not the widget parent size.

in your widget before applying the layout changes:

minimumWindowSize = this->window().size();

when you finished reorganizing the widget to the compact size

this->window().resize(minimumWindowSize);
Candycecandystriped answered 20/2, 2013 at 13:19 Comment(2)
thank you, i will try that in a few minutes. the fact is, there are many different combinations of resolutions, from 320x240 up to 1280x1024. It would take up to 10 size configurations. Is there no way Qt does this automatically?Brooklet
I did not test it, but you might try by only storing the minimum size (or even providing a null size). If I am correct QT should automatically increase the window size to the minimum value to display all the contained widgetsCandycecandystriped
M
1

Resolution of OS doesn't matter. I had to only have a widget for rendering video, or image in your case.

void MainWindow::resizeEvent(QResizeEvent* event)
{
   QMainWindow::resizeEvent(event);
   if ((player != 0) && ((player->isPlaying()) || player->isLoaded() || player>isLoaded())){
       renderer->resize(ui->mainVideoWidget->width(),ui->mainVideoWidget->height());
       resizeFilter();
   }
}
Mahmoud answered 18/2, 2014 at 9:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.