QMainWindow::show() breaks QMenuBar::cornerWidget()
-
I have an issue that I have been able to recreate in QtCreator :
Here is my QtCreator .ui file below. It is a empty basic QMainWindow with a QMenuBar containing 5 actions.
<?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>MainWindow</class> <widget class="QMainWindow" name="MainWindow"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>1085</width> <height>300</height> </rect> </property> <property name="windowTitle"> <string>MainWindow</string> </property> <widget class="QWidget" name="centralWidget"/> <widget class="QToolBar" name="mainToolBar"> <attribute name="toolBarArea"> <enum>TopToolBarArea</enum> </attribute> <attribute name="toolBarBreak"> <bool>false</bool> </attribute> </widget> <widget class="QStatusBar" name="statusBar"/> <widget class="QMenuBar" name="menuBar"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>1085</width> <height>20</height> </rect> </property> <widget class="QMenu" name="menuFile"> <property name="title"> <string>File</string> </property> </widget> <widget class="QMenu" name="menuEdit"> <property name="title"> <string>Edit</string> </property> </widget> <widget class="QMenu" name="menuCreate"> <property name="title"> <string>Create</string> </property> </widget> <widget class="QMenu" name="menuWindow"> <property name="title"> <string>Window</string> </property> </widget> <widget class="QMenu" name="menuHelp"> <property name="title"> <string>Help</string> </property> </widget> <addaction name="menuFile"/> <addaction name="menuEdit"/> <addaction name="menuCreate"/> <addaction name="menuWindow"/> <addaction name="menuHelp"/> </widget> </widget> <layoutdefault spacing="6" margin="11"/> <resources/> <connections/> </ui>
Here is my mainwindow.cpp, my only source file in my project (except the main.cpp which I did not modify).
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QDebug> #include <QHBoxLayout> #include <QMenuBar> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); this->setGeometry(100,100,1306,722); QMenuBar* menuBar = this->menuBar(); //creating a QFrame cornerwidget containing a HBoxLayout QFrame* corner_widget_frame = new QFrame(menuBar); QHBoxLayout* corner_widget_layout = new QHBoxLayout(); corner_widget_layout->setMargin(4); corner_widget_layout->setSpacing(0); corner_widget_frame->setLayout(corner_widget_layout); corner_widget_frame->setAutoFillBackground(false); corner_widget_frame->setStyleSheet("background-color: #FF0000;"); menuBar->setCornerWidget(corner_widget_frame); //bring to front setWindowState( (windowState() & ~Qt::WindowMinimized) | Qt::WindowActive); show(); activateWindow(); //bring to front END //create test widget QWidget* blue_widget = new QWidget(); //no parent blue_widget->setFixedSize(40,5); blue_widget->setStyleSheet("background-color:blue;"); //create test widget END //adding my widget to the corner_widget_frame this->menuBar()->cornerWidget()->layout()->addWidget(blue_widget); } MainWindow::~MainWindow() { delete ui; }
If you run this code in the QtCreator, you will see that the blue_widget is barely visible up in the top right corner. The majority of the widget is cut off from the main window. If I resize the main window horizontally the corner widget will appear correctly permanently.
However, if you put the bring to front code at the end of the file, after the blue_widget is added, the widget is correctly displayed. I saw that if I comment out the QMainWindow::show() call in the code I posted above, I do not have my problem and the window is correctly displayed (not hidden), giving me the impression that in my current case the call to QMainWindow::show() is not only causing the problem but is also useless.
I am working on an already existing application, I created this QtCreator project to isolate and replicate the issue. I did not add the QMainWindow::show() call myself in the application. Removing the QMainWindow::show() call in my application fixes my problem and doesn't seem to cause any issue, but I am afraid to remove it since I think it could cause other issues I don't see in my preliminary tests. Also in the application there is a certain period of time and several things happening between the time the bring to front code is executed and the widget is added to the corner widget(if it is added at all), meaning I cannot add my widget when my QMenubar is having it's corner widget created or before the QMainWindow::show() call.
According to documentation, all QWidget::show() does is litteraly show the widget and its parents. I have tried (in my QtCreator project and the application) to call QWidget::update(), QWidget::updateGeometry() and QWidget::show() on the QMainWindow, the QMenubar, the corner widget and the (blue)test_widget after adding my (blue)test_widget, to no avail. I also tried calling menuBar->adjustSize() but I did not see any changes.
I have also noticed that if I completely remove the QMenubar (meaning the 5 actions are gone) from my QMainWindow (with the QtCreator ui editor), the QMainWindow::show() call will not cause the issue and my corner widget will display properly.
So what does QMainWindow::show() do under the hood exactly ? Why is it causing this issue ? Is the QMainWindow::show() necessary ?
Thanks for the help.
-
Hi and welcome to devnet,
You don't need to call show in your widget constructor. In your case, it's already done in the main function of your main.cpp file.
There's also no need for your "bring to front" code especially in the constructor. You are trying to show the widget before you finish initializing it.
-
Hi SGaist and thank for the help.
For the code being in the constructor when it should not be, I only did it that way to have the simplest code possible to show my issue. I understand and agree with your point. I am working on an already existing application, I created this QtCreator project to isolate and replicate the issue. I do not call QWidget::show() in the constructor of my application.
I have made an important discovery while working on this issue: calling blue_widget->show() at the end of my code in my QtCreator project does fixe the problem, but doing the same in my application does not fix the issue. This is the 1st time I see a different behavior, I thought I had manage to have the same 1:1 behavior between the QtCreator project and my application.
Thanks for the help, I will keep looking.