我正在使用典型的主窗口GUI界面编写程序,其中QMainWindow
和QMdiWindow
Qt 5.4类与下图(来自official documentation)类似。
每次活动子窗口更改时,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));
}