Irregular access violation when switching active subwindow in an MDI application
-
Hi,
I'm getting an access violation when switching active subwindow in an MDI application. There is no simple repeatable procedure which triggers the access violation every time the a specific user pattern is followed but it's possible to get the access violation without much effort if one is adding and closing subwindows a few times and then invokes any of the MDI application window actions (Tile, Cascade, Next, Previous).
Comparing my application to the MDI example application the only difference I find is that my application invokes setAttribute(Qt::WA_DeleteOnClose); on the MDI child windows.
I would guess that's it's related to that the MDI area for some reason doesn't know that some subwindows has been removed, invoking methods in those now deleted subwindows. Can it be that QMdiArea::removeSubWindow should be invoked at some stage when WA_DeleteOnClose is used? But the MDI children at least isn't showed in the MDI area once they've been closed hence the MDI area at least in some aspects knows that the child window has been removed.
Screenshot of Qt Creator debugger when the issue occurs
Using Qt 5.15.1
Anyone with ideas on how to track this down?
-
Hi,
Are you using addSubWindow as shown in the documentation ?
-
I think so. The code is as follows with some company internal names changed to X. XMdiSubWindow inherits QMdiSubWindow to add some options to the system menu, that's all. XMdiSubWindow declares Q_OBJECT. XTable inherits QWidget and have subWindows as parent.
XMdiSubWindow *subWindow = new XMdiSubWindow(this); subWindow->setAttribute(Qt::WA_DeleteOnClose); XTable *child = new XTable(subWindow, characteristicCoordinator_); subWindow->setWidget(child); addSubWindow(subWindow);
-
Are you giving a parent to XTable ?
-
What happens if you don't ?
-
Do you get the same issue if you create a default application and use the code from the documentation as is ?
-
I modified the mdi example to read
MdiChild *MainWindow::createMdiChild() { MdiChild *child = new MdiChild; QMdiSubWindow *subWindow1 = new QMdiSubWindow; subWindow1->setWidget(child); subWindow1->setAttribute(Qt::WA_DeleteOnClose); mdiArea->addSubWindow(subWindow1); #ifndef QT_NO_CLIPBOARD connect(child, &QTextEdit::copyAvailable, cutAct, &QAction::setEnabled); connect(child, &QTextEdit::copyAvailable, copyAct, &QAction::setEnabled); #endif return child; }
i.e. to be according to the documentation. That seems to work fine.
-
-
@olowo726
:) As I thought! In which case, only me, but I'd want to know what is different about their example code compared to your original attempt? Maybe if you retry your original attempt it will work now?! Anyway, up to you, you can just stick with what you do have working now. -
I've solved this now but actually I don't know exactly why.
My application have several MDI areas which the user can switch between. I had forgotten to disconnect the tile etc. menu choices from the old MDI are when the user switched MDI area. When I corrected that the crash disappeared as well indicating that the old signal connections somehow loomed. However I don't know why, I think that the signals should have been automatically disconnected when the objects were destroyed.