1

I'm coding a program with a typical main window GUI interface with the QMainWindow and QMdiWindow Qt 5.4 classes similar to the one of the below picture (from the official documentation).

Qt MDI

Every time the active subwindow changes the updateWindowMenu() method is called and it clears and repopulates the Window menu with QActions pointing to one of each subwindows, that is it, when you click an action the subwindow associated with this action will be brought to the front and will become the active subwindow. The association is done with QSignalMapper because updateWindowMenu() needs the current active subwindow (if any).

The problem arises when I click an action, its signal is not triggered and hence the subwindow associated is not brought to the front. After investigating I realised that what hampers the action triggering is the call to menuWindow->removeAction(mySubwindowActions->at(n)) (menuWindow comes from an .iu file created with Qt Designer). That is it, if I comment out

// for (int n=0; n<mySubwindowActions->size(); ++n)
//    menuWindow->removeAction(mySubwindowActions->at(n));

duplicated actions to the Window menu will be added every time updateWindowMenu() is called but they will work as expected and they will bring to the front the associated subwindow.

Why this anomalous behaviour? How can I remove actions without hindering the normal working of new added actions?

WindowMain.h

class WindowMain : public QMainWindow, public Ui::mainWindow {
    Q_OBJECT

    private:
        QSignalMapper* mySignalMapper;
        QList<QAction*>* mySubwindowActions;

    private slots:
        void updateWindowMenu(QMdiSubWindow*);
        void setActiveSubWindow(QWidget*);
}

WindowMain.cpp

void WindowMain::WindowMain() {
    connect(myMdiArea, &QMdiArea::subWindowActivated, this, &WindowMain::updateWindowMenu);

    mySignalMapper = new QSignalMapper(this);
    connect(mySignalMapper, static_cast<void (QSignalMapper::*)(QWidget*)>(&QSignalMapper::mapped), this, &WindowMain::setActiveSubWindow);

    mySubwindowActions = new QList<QAction*>();
}


void WindowMain::updateWindowMenu(QMdiSubWindow* mdiSubwindow) {
    for (int n=0; n<mySubwindowActions->size(); ++n)
        menuWindow->removeAction(mySubwindowActions->at(n));
    mySubwindowActions->clear();

    if (mdiSubwindow != 0) {
        QList<QMdiSubWindow*> subwindows = myMdiArea->subWindowList();
        for (int n=0; n<subwindows.size(); ++n) {
            QAction* actionSubwindow = menuWindow->addAction(subwindows.at(n)->widget()->windowTitle());
            mySubwindowActions->append(actionSubwindow);
            mySignalMapper->setMapping(actionSubwindow, subwindows.at(n));
            connect(actionSubwindow, &QAction::triggered, mySignalMapper, static_cast<void (QSignalMapper::*)()>(&QSignalMapper::map));
        }
    }
}


void WindowMain::setActiveSubWindow(QWidget* subWindow) {
    myMdiArea->setActiveSubWindow(qobject_cast<QMdiSubWindow*>(subWindow));
}
AxeEffect
  • 6,345
  • 4
  • 37
  • 33

0 Answers0