QSignalMapper 这个类并不是个新鲜概念, 早在 Qt2 里就已经存在, 而且它的功能也是始终如一。 不过由于宣传力度不够(例子里涉及到它的很少)了解这个类人可能还不是很多, 所以特此撰文介绍此类的功能和用法。
简单的理解,可以把 SignalMapper 这个类看成是信号的翻译和转发器, 它可以把一个无参数的信号翻译成带 int 参数、 QString 参数、 QObject* 参数或者 QWidget* 参数的信号, 并将之转发。 这么一说大家有没有联想到该类的适用范围呢? 呵呵, 是不是一下就想到了如果我有一堆的 button , 可以把 clicked 事件放在一个函数里处理, 只要给 button 编个号或者给 button 起个名就行了, 这样就不用给每个 button 写一个 slot 了,岂不是很方便?
下面这段代码就实现了该功能:
//mainwin.h
class MainWin : public QWidget
{
Q_OBJECT
public:
MainWin(QWidget *parent = 0);
private slots:
void doClicked(const QString & btnname);// 处理最终信号的槽
private:
QSignalMapper *signalMapper;
};
//mainwin.cpp
MainWin::MainWin(QStringList texts, QWidget *parent) : QWidget(parent)
{
QString buttontext = "btn1,btn2,btn3,btn4,btn5,btn6,btn7,btn8,btn9,btn10";//10 个 button
QStringList texts = buttontext.split(",");
signalMapper = new QSignalMapper(this);
QGridLayout *gridLayout = new QGridLayout;
for (int i = 0; i < texts.size(); ++i)
{
QPushButton *button = new QPushButton(texts[i]);
connect(button, SIGNAL(clicked()), signalMapper, SLOT( map ()));
// 原始信号传递给 signalmapper
signalMapper-> setMapping (button, texts[i]);
// 设置 signalmapper 的转发规则 , 转发为参数为 QString 类型的信号,
// 并把 texts[i] 的内容作为实参传递。
gridLayout->addWidget(button, i / 3, i % 3);
}
connect(signalMapper, SIGNAL( mapped (const QString &)),
this, SLOT(doClicked(const QString &)));// 将转发的信号连接到最终的槽函数
setLayout(gridLayout);
}
void MainWin::doClicked(const QString& btnname)
{
QMessageBox::information(this, "Clicked", btnname + " is clicked!");// 显示被按下的 btn 名称。
}
从这个例子来看 QSignalMapper 的用法是非常简单的, 也很容易理解。
*首先把原始不带参数的信号连接到 signalmapper 的 map 槽函数, 这样 signalmapper 能在第一时间接收到原始信号;
*其次调用 setMapper 方法告诉 signalmapper 怎样去处理原始信号。 在这个例子中是把原始信号转化为一个带 QString 参数的信号
*最后接收转化后的带参数信号, 这里所把转化后的信号与槽函数连接, 在槽函数中获得需要的数据。
原文地址:http://www.cuteqt.com/blog/?p=512