Qt 动态生成的菜单项--确定单击了哪个菜单项

Qt 动态生成的菜单项--确定单击了哪个菜单项,qt,Qt,我正在解析一个包含菜单栏项列表的XML文档。换句话说,如果XML树中有5个元素,那么我将创建5个QAction*变量,并将它们添加到QMenu中。因此,项目的数量是动态的,在编译时是未知的 问题在于如何进行回调。由于我不知道QAction*变量的数量,我不能简单地为每个变量创建回调: connect(action, SIGNAL(clicked()), this, SLOT(item1Clicked())); connect(anotherAction, SIGNAL(clicked()), t

我正在解析一个包含菜单栏项列表的XML文档。换句话说,如果XML树中有5个元素,那么我将创建5个
QAction*
变量,并将它们添加到
QMenu
中。因此,项目的数量是动态的,在编译时是未知的

问题在于如何进行回调。由于我不知道
QAction*
变量的数量,我不能简单地为每个变量创建回调:

connect(action, SIGNAL(clicked()), this, SLOT(item1Clicked()));
connect(anotherAction, SIGNAL(clicked()), this, SLOT(item2Clicked()));
connect(yetAnotherAction, SIGNAL(clicked()), this, SLOT(item3Clicked()));
....
我考虑创建一个回调:

void menuItemClicked(int index)
但问题是我无法将无参数的
clicked()
信号连接到
menuItemClicked(int)
插槽

还有什么其他策略

更新——走了这么远 然后

void MainWindow::MainWindow()
{
QdomeElement rootElement=doc.documentElement();
QDomNodeList节点=doc.elementsByTagName(“文档”);
QMenu*documentationMenu=helpMenu->addMenu(“文档”);
QSignalMapper*signalMapper=新的QSignalMapper(此);
对于(int i=0;i设置映射(操作,i);
文档菜单->添加操作(操作);
}
}
连接(信号映射器,信号(映射(int)),此,插槽(帮助文档(int));
}
这些项目会添加到菜单栏,但不会调用helpDocumentation(int)插槽。

只需在插槽中使用sender()函数,它将告诉您哪个QAction触发了信号

QObject * s = sender();

if(s==action)
{
    //Do something here
}
else if(s==anotherAction)
{
    //Do something here
}
else if(s==yetAnotherAction)
{
    //Do something here
}
如果绝对需要索引参数,请查找QSignalMapper。它的功能正是您想要的:将多个无参数信号连接到单个插槽,将一个参数作为整数,为每个连接的信号关联一个唯一的整数索引

首先创建信号映射器:

QSignalMapper * signalMapper = new QSignalMapper(this);
将每个信号连接到signalMapper map()插槽:

然后告诉信号映射器哪个发送方有哪个索引:

signalMapper->setMapping(action, 0);
signalMapper->setMapping(anotherAction, 1);
signalMapper->setMapping(yetAnotherAction, 2);
然后将出站映射(int)信号连接到插槽

connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(menuItemClicked(int)));
顺便说一句,signalmapper是一个非常简单的类,它使用sender()并在哈希表中查找将QObject*sender与整数索引关联的数据。

一个选项是使用galinette指出的


更专门的操作:。为此,您可以将元数据附加到您的操作中,在处理信号时可以使用这些元数据进行访问。

感谢您的回答--我现在终于理解了QSignalMapper。我试图实现您的解决方案,但不幸的是,插槽没有被调用。我编辑了我的帖子以显示代码。你能看到出了什么问题吗?正如蒂尔曼所注意到的,QAction没有clicked()信号。替换为triggered()。
QAction
没有
clicked()
信号。使用
信号(triggered())
代替。谢谢Tilman的回答。顺便说一下,连接一个不存在的信号应该会在控制台中产生一个警告。
QSignalMapper * signalMapper = new QSignalMapper(this);
connect(action, SIGNAL(triggered()), signalMapper, SLOT(map()));
connect(anotherAction, SIGNAL(triggered()), signalMapper, SLOT(map()));
connect(yetAnotherAction, SIGNAL(triggered()), signalMapper, SLOT(map()));
signalMapper->setMapping(action, 0);
signalMapper->setMapping(anotherAction, 1);
signalMapper->setMapping(yetAnotherAction, 2);
connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(menuItemClicked(int)));