QSignalMapper用法

    技术2022-05-20  60

            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


    最新回复(0)