我正在解析一个包含菜单栏项列表的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)
广告位。
还有其他策略吗?
class MainWindow
{
private slots:
void helpDocumentation(int);
...
然后
void MainWindow::helpDocumentation(int index)
{
// do some logging
}
和
void MainWindow::MainWindow()
{
QDomElement rootElement = doc.documentElement();
QDomNodeList nodes = doc.elementsByTagName("document");
QMenu * documentationMenu = helpMenu->addMenu("Documentation");
QSignalMapper * signalMapper = new QSignalMapper(this);
for (int i = 0; i < nodes.length(); ++i)
{
QDomNode node = nodes.item(i);
QDomElement element = node.toElement();
if (!element.isNull())
{
// Item is an element.
QString fileAttr = element.attribute("file");
QString nameAttr = element.attribute("name");
documentationItems.push_back(qMakePair(fileAttr, nameAttr));
QAction * action = new QAction(nameAttr, helpMenu);
connect(action, SIGNAL(clicked()), signalMapper, SLOT(map()));
signalMapper->setMapping(action, i);
documentationMenu->addAction(action);
}
}
connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(helpDocumentation(int)));
}
项目将添加到菜单栏,但不会调用helpDocumentation(int)插槽。
答案 0 :(得分:4)
只需使用插槽内的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()插槽:
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);
然后将出站映射(int)信号连接到您的插槽
connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(menuItemClicked(int)));
顺便说一句,signalmapper是一个非常简单的类,它使用sender()并查找将QObject *发送者与整数索引相关联的哈希表。
答案 1 :(得分:3)
一种选择是使用galinette指出的QSignalMapper
。
更专注于行动:QActionGroup
。为此,您可以使用QAction::setData()
将元数据附加到您的操作,您可以在处理QActionGroup::triggered(QAction *)
信号时访问这些数据。