Situation: As the central widget of my application I have a QMdiArea in tabbed mode (wrapped in a custom class that inherited from QMdiArea). When I now add the first QMdiSubWindow via addSubWindow()
everything is still fine, meaning the window and its contents are maximized to take up all the space of the QMdiArea. However, as soon as I add a second sub window, the following problem arises:
Problem: The content of the second window is not displayed, but instead the content from the first continues to (despite the fact that the second tab visually has the focus), but is reduced in size. It only takes up a few pixels. But if I now switch back to the first sub window/tab (either by clicking into the size-reduced widget which then automatically goes back to max size or by selecting the first tab header) and then selecting the 2nd again, all is fine = the widget/editor of the 2nd tab is now displayed and is maximized.
But only until I close the second tab, in which case the content from the first is displayed (as expected), but again only in the small size!
Screenshot:
Another related test case: 1st tab is created and is displayed full size as expected. If I now simply resize the overall QMainWindow, suddenly a faint border appears around the widget in my tab. So it appears to be in a mixed state between maximized and normal mode with borders. Does that create any new leads?
Screenshot:
I am so far not using any explicitly defined layouts, but given that the first tab works fine and after manual back-and-forth switching all others as well, I assume that it should work without.
Do I need to set explicit layout objects? Why does it work for the first tab, but not the second?
Some code as a base: This is the logic executed in my custom QMdiArea class that takes care of adding the new children:
// Note: pEditor inherits from / is a QMdiSubWindow itself
if(!pEditor->isInitialized())
{
pEditor->initialize();
pEditor->setWidget(pEditor->getEditorWidget());
pEditor->setInitialized(true);
}
pEditor->beforeDisplay();
addSubWindow(pEditor);
pEditor->showMaximized();
// HACK START
pExisting = subWindowList().at(0);
if(pExisting)
setActiveSubWindow(pExisting);
// HACK END
Update: Added the hack proposed by N1ghtLight. Marked as such in the coding.
Update 2: Edited / correct problem description + new test-case with screenshot.
After many hours of comparing the example project from N1ightLight to my own implementation, I finally came across the central differences. There were in fact two issues at play:
For some reason I had the following line in the creation of my MDI sub windows, which apparently screwed up the size handling. Getting rid of this line removed any need for the previously proposed hack. Combined with the layouting proposed by N1ghtLight, all size changes are now handled gracefully.
setWindowState(Qt::WindowMaximized); // do not use that state!
The second part regarding the tab closing (closing one tab did not bring up the next tab in the expected manner and size), is actually explained in the Qt documentation:
When you create your own subwindow, you must set the Qt::WA_DeleteOnClose widget attribute if you want the window to be deleted when closed in the MDI area. If not, the window will be hidden and the MDI area will not activate the next subwindow.
Since I was creating my own sub windows I had to set that flag, but I never did because I wanted to prevent Qt from automatically deleting my content widget as well. My solution now is that I set the flag, but whenever a MDI child is about to be closed, I remove the link to the widget, so Qt cannot delete it.
void CustomMDIWindow::closeEvent(QCloseEvent* pEvent)
{
setWidget(0);
pEvent->accept();
}
I will mark my own answer as the correct one, but will award the bounty to N1ightLight since his support eventually led to me finding the final solution.