Important: Please read the Qt Code of Conduct -

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?

  • Lifetime Qt Champion


    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);
    XTable *child = new XTable(subWindow, characteristicCoordinator_);

  • Lifetime Qt Champion

    Are you giving a parent to XTable ?

  • yes, subWindow is the parent.

  • Lifetime Qt Champion

    What happens if you don't ?

  • Same thing, no difference

  • Lifetime Qt Champion

    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;
    #ifndef QT_NO_CLIPBOARD
        connect(child, &QTextEdit::copyAvailable, cutAct, &QAction::setEnabled);
        connect(child, &QTextEdit::copyAvailable, copyAct, &QAction::setEnabled);
        return child;

    i.e. to be according to the documentation. That seems to work fine.

  • @olowo726
    The difference appears to be that you subWindow1->setAttribute(Qt::WA_DeleteOnClose); after subWindow1->setWidget(child);, in your earlier one you set it before setting the child widget, does that really alter the behaviour?

  • No difference (just tested)

  • @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.

  • Sorry, I formulated myself badly, regarless of the order of the statement the application crashes.

  • 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.

  • Lifetime Qt Champion


    Did you verify the objects were actually destroyed?
    Else that would explain why they are still connected.

Log in to reply