How to Set QMainWindow Size?
-
@Andaharoo the resize event should work as suggested by @KillerSmath
MainWindow w; w.resize(500,500); w.show();
Pass the appropriate size as per your Widget in it.
In case if you still have some issue with your code then please check QResizeEvent which can help you.
https://doc.qt.io/qt-5/qresizeevent.html -
This has not been satisfactorily answered. I have the same or similar issues. For example if a QMainWindow subclass has a central widget, with children and layout managers; then if widgets are hidden and variable size widgets like QTextEdit are visible it seems impossible to change the size of the window from code. The layouts seem to always take account of hidden widgets and grow the variable size visible widgets as a result. Is there some way to force the layout to respect the currently visible widgets and the size of the window? Even using layout ()->removeWidget(widget_ptr) before hiding the widgets doesn't seem to remove their influence on sizing!!
-
@bsomervi Please provide a minimal, compileable example - it works by calling setSize() accordingly.
-
@bsomervi said in How to Set QMainWindow Size?:
what class is setSize a member of?
I meant QWidget::resize() which changes the size property
-
OK, so here's an example. The intention is to have two main window states, one showing two resizable widgets and the other only showing one. The idea is that the one widget display is a short-form version to save screen space. Build and run, size the main window to some large size, check the menu action then move and resize the single widget version, specifically make it as small as possible. From that point I want the menu action to flip between the two main window sizes, but it doesn't. The one widget size increases and that increase is something to do with the hidden widget.
-
Sorry, messed up the repro example with last minute simplifications, this one actually builds and runs:
#include <QApplication> #include <QMainWindow> #include <QWidget> #include <QTextEdit> #include <QVBoxLayout> #include <QAction> #include <QMenuBar> #include <QMenu> class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow () : central_widget_ {new QWidget {this}} , edit_ {new QTextEdit {central_widget_}} , hideable_edit_ {new QTextEdit {central_widget_}} , layout_ {new QVBoxLayout} , resize_action_ {new QAction {"&Resize"}} { setCentralWidget (central_widget_); layout_->addWidget (edit_); layout_->addWidget (hideable_edit_); central_widget_->setLayout (layout_); resize_action_->setCheckable (true); action_menu_ = menuBar ()->addMenu (tr ("&Action")); action_menu_->addAction (resize_action_); connect (resize_action_, &QAction::toggled, this, &MainWindow::do_resize); } private: Q_SLOT void do_resize (bool checked) { auto s = size (); hideable_edit_->setVisible (!checked); if (saved_size_.isValid ()) { // here I want to have the user resizeable main window flipped // as if the lower QTextEdit just disappeared/reappeared, i.e. the top // QTextEdit remains exactly as is (i.e. as resized by the // user resizing the main window) // // I want the user to be able to move and resize the main // window in either state and then the menu action flips // between them. It doesn't restore the size if the user // shrinks the main window below a certain size. resize (saved_size_); } saved_size_ = s; // save for when we flip back } QWidget * central_widget_; QTextEdit * edit_; QTextEdit * hideable_edit_; QVBoxLayout * layout_; QAction * resize_action_; QMenu * action_menu_; QSize saved_size_; }; int main (int argc, char * argv[]) { QApplication app {argc, argv}; MainWindow main_window; main_window.show (); QApplication::connect (&app, &QApplication::lastWindowClosed, &app, &QApplication::quit); return app.exec (); } #include "main.moc"
-
Hello!
You can try to use therestoreGeometry
method - https://doc.qt.io/qt-5/qwidget.html#restoreGeometryHere is my example (main.cpp):
#include <QApplication> #include <QWidget> #include <QMainWindow> #include <QPushButton> int main(int argc, char *argv[]) { QApplication a(argc, argv); QMainWindow window; window.setWindowTitle("Test MainWindow"); QWidget widget; widget.setMinimumSize(400, 300); window.setCentralWidget(&widget); QPushButton *testBtn = new QPushButton("Restore size", &window); testBtn->setFixedSize(150, 100); window.show(); QByteArray savedGeometry = window.saveGeometry(); QObject::connect(testBtn, &QPushButton::clicked, [&window, savedGeometry]() { if (!savedGeometry.isNull() && !savedGeometry.isEmpty()) { window.restoreGeometry(savedGeometry); } else { window.setGeometry(window.geometry().x(), window.geometry().y(), 400, 300); } }); return a.exec(); }
Result:
Happy coding!
-
I have tried your code, fixed a few compile errors, but for me it works well.
Result:
What are you trying to achieve? By the way, you can use
QSplitter
https://doc.qt.io/qt-5/qsplitter.html with layout to hide thehideable_edit_
(QTextEdit
).Also, there are two options you can try:
- Use
QResizeEvent
https://doc.qt.io/qt-5/qresizeevent.html - Use
nativeEvent
https://doc.qt.io/qt-5/qwidget.html#nativeEvent to intercept and handle the resize/restore window messages (https://docs.microsoft.com/en-us/windows/win32/winmsg/wm-size, https://docs.microsoft.com/en-us/windows/win32/winmsg/wm-sizing)
- Use
-
The problem is when the single widget rendering is shrunk using the mouse to the minimum size toggling the action twice does not restore the main window size. I can find no way to set the size of the main window as small as it was settable using the mouse. This is a problem (a) because there seems to be no way to do in code what can be done with the mouse, and (b) the whole point is to have a "view" of the main window set by the user that can be returned to using the code. Users simply cannot believe we can't do this and their chosen size is ignored.
-
native events are no use to us as our application is portable. How do i use resizeEvents to do this? Note that my real case has a whole bunch of widgets and layouts in the hideable part, I don't think a splitter is appropriate as the bottom part is not resizable. I just used another QTextEdit in my example above as the header was already included.
-
@Cobra91151 where are the compile errors in my code example?
You second animation above clearly shows the issue I am trying to solve.
How do I make use of an override resizeEvent() to fix this issue? I don't see how it can help, a resize Event is triggered by some external action, how can I make it fix the specific when a call to MainWindow::resize() does not do what it is asked to do?
-
What do you mean portable? I suppose your app must run on different operating systems? If so, then check out this link: https://forum.qt.io/topic/104533/how-to-ignore-the-event-when-i-click-on-the-button-to-maximize-the-window-windowmaximizebuttonhint/9
You can use
nativeEvent
with defines for different operating systems and add the appropriate code. -
As for compile errors: you forgot to add & in two connects. Example below:
Your code:
connect(resize_action_, QAction::toggled, this, &MainWindow::do_resize);
QApplication::connect(&app, QApplication::lastWindowClosed, &app, QApplication::quit);
Fixed:
connect(resize_action_, &QAction::toggled, this, &MainWindow::do_resize);
QApplication::connect(&app, &QApplication::lastWindowClosed, &app, QApplication::quit);
-
OK, so here's another related frustration. My real code persists the state of the checkable action into a settings file. On startup it builds the UI and then if the action is checked hides the lower widget(s). This is all in the main window constructor. It then goes on to restore the reduced size main window using MainWindow::restoreGeometry(geometry) also from the settings file stored at shutdown with QMainWindow::saveGeometry(). This shows the correctly sized main window. If I then toggle the action twice the main window size then is bigger. This is really annoying. Why does MainWindow::restoreGeometry() work in the constructor before the first QMainWindow::show() and yet after that neither MainWindow::restoreGeometry(), nor QMainWindow::resize(), nor any other way of trying to set the size, I have tried so far, work correctly.
I have tried removing the lower widget(s) from the layout. I have tried hiding the whole main window before making the size adjustments and showing again afterwards (although I guess this is a no-op as i don't get into the event loop between the calls).
I must be missing the necessary incantation to make these sizing member functions work correctly.
-
@Cobra91151 Note also that this misbehaviour is the same on Windows, Linux, and macOS, so I don't think it is anything to do with native control renderings. It is something in Qt that is causing hidden widgets to influence the minimum size of a window when they should not.
-
Hidden widgets are not used by the sizeHint() calculation. Still no example which shows the opposite.