从QMenu中移除QAction后未触发QAction

时间:2015-06-30 09:03:07

标签: c++ qt qmenu qaction

我正在使用典型的主窗口GUI界面编写程序,其中QMainWindowQMdiWindow Qt 5.4类与下图(来自official documentation)类似。

Qt MDI

每次活动子窗口更改时,updateWindowMenu()方法都会被调用,它会清除并重新填充Window菜单,其中QActions指向每个子窗口中的一个,也就是说,当您单击时与此操作关联的子窗口将被置于前面,并将成为活动子窗口。关联是使用QSignalMapper完成的,因为updateWindowMenu()需要当前有效的子窗口(如果有)。

当我点击一个动作时,问题就出现了,它的信号没有被触发,因此相关的子窗口没有被带到前面。在调查之后,我发现阻碍动作触发的是调用menuWindow->removeAction(mySubwindowActions->at(n))menuWindow来自使用Qt Designer创建的.iu文件)。就是这样,如果我发表评论

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

每次调用Window时都会添加updateWindowMenu()菜单的重复操作,但它们会按预期工作,并且会将相关子窗口带到前面。

为什么会出现这种异常行为?如何在不妨碍新添加操作的正常工作的情况下删除操作?

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));
}

0 个答案:

没有答案