我正在编写一个带有典型主窗口 GUI 界面的程序,其中QMainWindow
Qt QMdiWindow
5.4 类类似于下图之一(来自官方文档)。
每次活动子窗口更改时,updateWindowMenu()
都会调用该方法,并通过指向每个子窗口之一来清除并重新填充Window
菜单QActions
,也就是说,当您单击一个动作时,与该动作关联的子窗口将被带到前面,并将成为活动子窗口。关联已完成,QSignalMapper
因为updateWindowMenu()
需要当前活动的子窗口(如果有)。
当我单击一个动作时会出现问题,它的信号没有被触发,因此相关的子窗口没有被带到前面。经过调查,我意识到阻碍动作触发的是对menuWindow->removeAction(mySubwindowActions->at(n))
(menuWindow
来自.iu
使用 Qt Designer 创建的文件的调用)。就是这样,如果我注释掉
// 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));
}