我有一个带有许多子菜单的 QMenu。这些是动态创建的,即名称菜单来自数据库并在循环中创建。现在我想在单击菜单时触发相同的 slottrigger() 或类似的,但我需要将 QString 菜单名称传递给 slot,以便我可以执行特定于菜单的操作。我已经尝试过了,即将一个 QAction * 传递给触发的事件并使用了 setData 但我得到了运行时错误。
object::connect: 没有这样的信号 QAction::triggered(QAction *)
for(int j=0; j<channelTypes[i].getNumChannels() ; j++){
QAction *subMenuAct = subMenu->addAction(tr(c_name)); // c_name the menu name
subMenuAct->setData(ch_name);
connect(subMenuAct, SIGNAL(triggered(QAction *)), this, SLOT(playChannel(QAction *))); // playChannel is the slot
}
void <ClassName>::playChannel(QAction *channelAction)
{
QString str = channelAction->data().toString();
qDebug() << "Selected - " << str;
}
或者,我也尝试过 QSignalMapper ,其中 signalMapper 是在构造函数中初始化的数据成员
signalMapper = new QSignalMapper(this);
和
for(int j=0; j<channelTypes[i].getNumChannels() ; j++){
QAction *subMenuAct = subMenu->addAction(tr(c_name));
connect(subMenuAct, SIGNAL(triggered()), signalMapper, SLOT(map()));
signalMapper->setMapping(subMenu, ch_name);
connect(signalMapper, SIGNAL(mapped(QString)), this, SLOT(playChannel(QString)));
}
在第二种情况下,我没有收到任何错误,但是插槽函数 playChannel 没有被调用。如果有人可以帮助解决它,我将不胜感激。
更新 1:我从其他示例中看到的唯一区别是,通常人们将来自多个小部件的信号连接到一个插槽(比如不同的按钮)。在我的情况下,我将几个子菜单(具有不同的名称)连接到一个插槽。这应该有什么不同吗?
更新 2:它在以下解决方案中为 QSignalMapper 建议的更正后工作。此外,我使用 SubMenu 作为 setMapping 的参数,而应该使用 MenuAction 项。但是现在我多次触发事件,即与所选子菜单类别的主菜单中的条目一样多。如果频道类型是英语(主菜单),有四个条目)、HBO、明星电影等(子菜单),并且我选择 HBO,则使用字符串 HBO 触发事件四次。如果我为每个子菜单创建一个单独的信号映射器,它工作正常。但我希望应该使用一个映射器,我在这里做错了。答案的评论中有更多细节。