How to find out the initial size of a widget?
-
My program has class MyMainWindow (derived from QMainWindow). MyMainWindow contains a few widgets, which I have laid out with Qt Creator's tool Design.
I want MyMainWindow to start up as maximized, so the constructor looks like this:
MyMainWindow::MyMainWindow() :
QMainWindow(nullptr),
ui(new Ui::MyMainWindow())
{
ui->setupUi(this);
[other setup code]
showMaximized();
}This works: MyMainWindow starts as maximized, and the layout is as expected.
Now, I would like to make some adjustments to the logic of my program based on the exact initial size of a certain widget inside MyMainWindow. How can I do that?
By reimplementing QMainWindow::resizeEvent() and QMainWindow::showEvent():
void MyMainWindow::resizeEvent(QResizeEvent* event) { [some logging code] QMainWindow::resizeEvent(event); } void MyMainWindow::showEvent(QShowEvent* event) { [some logging code] QMainWindow::showEvent(event); }
I found out that:
- showEvent() is called once at start-up, but not with the maximized size
- resizeEvent() is called twice at start-up: the 1st time not with the maximized size, the 2nd time with the maximized size
So, in principle it would be possible to achieve my goal by reacting to the 2nd call to MyMainWindow::resizeEvent(). How reliable would that method be? Could it depend on the Qt version? Would it also work on other platforms (Linux for example)? Is there a better way to do this?
My environment: Qt 6, Windows 10, Microsoft Visual Studio 2019.
-
Hi, another approach is to delay those business decisions/changes until after MainWindow's constructor is done (and the QWidgets have all their resizing done) say via a lambda, include "qtimer.h" and
... ui->setupUi(this); [other setup code] showMaximized(); ... QTimer::singleShot(20,this,[this] { // ... the rest of the startup code, i.e. business decisions }); // end of MainWindow constructor
20 ms is usually enough time to allow all the QWidgets to resize twice properly.
-
Hi,
You can use the changeEvent and react on the event to get the size in the state of interest.
-
@SGaist I was unable to get your suggestion to work. This is what I tried:
void MyMainWindow::changeEvent(QEvent* event) { if (event->type() == QEvent::WindowStateChange) { [logging code] } if (event->type() == QEvent::ActivationChange) { [logging code] } QMainWindow::changeEvent(event); }
Running my code with the above MyMainWindow::changeEvent() (as well as with MyMainWindow::resizeEvent() and MyMainWindow::showEvent() from my original message) reveals that:
- The sequence of calls at start-up is:
(1) changeEvent() with type = WindowStateChange
(2) resizeEvent()
(3) showEvent()
(4) changeEvent() with type = ActivationChange
(5) resizeEvent() - The maximized size of MyMainWindow (and the corresponding sizes of the widgets contained in MyMainWindow, including the widget I am interested in) is not available until (5), i.e., not until the second call to resizeEvent().
As I wrote in my original message, I could react to the 2nd call to MyMainWindow::resizeEvent(). And we are back to the questions I already raised:
- How reliable would that method be?
- Could it depend on the Qt version?
- Would it also work on other platforms (Linux for example)?
- Is there a better way to do this?
- The sequence of calls at start-up is:
-
-
Hi, another approach is to delay those business decisions/changes until after MainWindow's constructor is done (and the QWidgets have all their resizing done) say via a lambda, include "qtimer.h" and
... ui->setupUi(this); [other setup code] showMaximized(); ... QTimer::singleShot(20,this,[this] { // ... the rest of the startup code, i.e. business decisions }); // end of MainWindow constructor
20 ms is usually enough time to allow all the QWidgets to resize twice properly.