How to automatically resize a window, after hiding several widgets?
-
Colleagues, please, tell me how to solve my problem. I am unable to reduce the size of the MainWindow to close the voids from hidden widgets.
Depending on certain operating modes of my program, several window widgets should appear or disappear. I had no problems with this.
All the widgets to which I told hide() in the body of the MainWindow class constructor - obediently disappeared, and then, using one still free interface button, I told them setVisible(true) - they also obediently appeared.
But, at the same time, an unpleasant problem with adjusting the window dimensions came to light. After hiding the widgets, the MainWindow has the same dimensions as with the visible widgets, but the resulting empty space is more or less fairly distributed between the vertical springs in the window layout. If manually, using the mouse, reduce the vertical size of the window, then it takes the correct dimensions, but does not want automatically to do this.
The manually compressed window, after setVisible (true), is perfectly rescaled to the desired layout, taking into account the "appeared" widgets.I was honestly trying to get the window to shrink vertically. After hide() I told him
this->resize(minimumSize());
I also tried
this->resize(minimumSizeHint());
after them (and without them)
this->adjustSize();
Even got the height of the shared container with the "disappeared" widgets and subtracted it from the total window height.
this->resize(this->size().width(), this->size().height() - ui->verticalLayoutInvisible->geometry().size().height());
To no avail!
How can I persuade the MainWindow to independently do what I do with the mouse - reduce the height to the minimum possible, taking into account the visible elements?
Thanks in advance for your reply,
Ogogon. -
@Ogogon said in How to automatically resize a window, after hiding several widgets?:
reduce the height to the minimum possible, taking into account the visible elements?
Correct me if I'm wrong, but AFAIK it's not possible to use the elements of a hidden widget for geometry calculations, since size policies and layout wont work or change as soon as the widget isn't visible anymore.
-
@Pl45m4 said in How to automatically resize a window, after hiding several widgets?:
Correct me if I'm wrong, but AFAIK it's not possible to use the elements of a hidden widget for geometry calculations, since size policies and layout wont work or change as soon as the widget isn't visible anymore.
I'm sorry, I don't know Qt very well yet, but something is wrong here...
Please take a look at my fourth code example, where I myself calculate the size by which to reduce the height of the window. This happens after the widgets are hidden.
I also have the following code:
qDebug() << ui->verticalLayoutInvisible->geometry().size().height() << this->size().height();
And when executed, it gives the following output:
101 499
This is quite consistent with the size of the hidden widget and the window as a whole. Thus, I can quite correctly calculate the amount by which I need to resize the window.
Why then does this method not work, if manually, with the help of the mouse, it is quite possible?
Maybe I am not adding any other calls to the my "resize" that are necessary for it to be applied?
Ogogon.
-
This is definitely a very tricky problem.
From my experience this is my understanding of how Qt works: Whenever you request the size of a widget (
minimumSize()
in your case) it does not do a recomputation. There are several methods that should actually recompute the layout, but they never help.I guess the best way is to first call
update()
to redraw the widget and recompute the layouts. However, you cannot immediately callthis->resize(minimumSize())
after callingupdate()
because the update gets delayed. This means that you also have to put the resize into the event loop (and hopefully it gets called after the update):update(); QMetaObject::invokeMethod(qApp, [=](){ resize(minimumSize()); });
If
update()
doesn't work, you can carefully try to callredraw()
instead. The difference is thatredraw
is executed directly andupdate
is queued into the event loop andupdate
will also merge multiple update events. If used carelessly you can easily destroy the performance of your app when callingredraw
.