简而言之,可以把SignalMapper这个类看成是信号的翻译和转发器, 它可以把一个无参数的信号翻译成带int参数、QString参数、QObject参数或者QWidget参数的信号, 比如, 有一堆的button, 可以把clicked事件放在一个函数里处理, 只要给button编个号或者给button起个名就行了, 这样就不用给每个button写一个slot了,这样是不是就很方便了呢!
下面用代码示例进行简单描述:比如在MainWindow的工具栏中创建多个Action。
1. 在工程类构造中将转发的信号连接到最终的槽函数:
// 创建消息映射
QSignalMapper *m_pMapper = new QSignalMapper(this);
if (m_pMapper)
{
connect(m_pMapper, SIGNAL(mapped(int)), this, SLOT(OnActions(int)));
}
2. 在MainWindow的工具栏中创建多个Action
bool ****::createAction(int nId, const QString &iconFile, const char *name)
{
if (iconFile.isEmpty() || !name || !name[0] || !m_pMapper)
{
return false;
}
// 创建 Action 并初始化
QAction *act = new QAction(QIcon(iconFile), name, this);
//设置 signalmapper 的转发规则, 转发为参数为 int 类型的信号, 并把 nId 的值作为实参传递。
m_pMapper->setMapping(act, nId);
//原始信号传递给signalmapper
connect(act, SIGNAL(triggered()), m_pMapper, SLOT(map()));
return true;
}
3. 至此,已经完成了源信号(QAction)和信号转发器(QSignalMapper)的绑定,以及QSignalMapper和源信号slot的连接
如果还需要获取已创建的Action以做它用,比如:要获取已经创建的Action添加在MainWindow的ToolBar中,则可以通过QSignalMapper中的成员mapping(…),以setMapping(…)时转发的类型,返回与nId关联的发送者QObject。
// 获取 Action
QAction *act = qobject_cast<QAction *>(m_pMapper->mapping(ID_BILL_VERIFY));
QToolBar *toolBar = new QToolBar(this);
// 添加至 toolBar
toolBar->addAction(act);
从以上例子相比可以看出QSignalMapper用法还是比较简单的,主要有以下三点:
- 把源信号(不带参)连接到SignalMapper的map槽函数上;
- 调用setMapper方法添加映射,以便当map()从给定的发送方发出信号时,发出映射的信号(id),每个发送者最多可以有一个整数ID。通俗的讲就是告诉SignalMapper如何去处理原始信号, 在文例中是把源信号转化为一个带int参数的信号;
- 接收转化后的带参数信号, 这里所把转化后的信号与槽函数OnActions(int)连接, 在槽函数中完成其他任务。