QSignalMapper 使用connect函数时向slot传递参数

https://blog.csdn.net/imred/article/details/72940365

设想这样一种场景:共有5个button,button1~button5,点击button1时输出“button 1 clicked”,点击button2时输出“button 2 clicked”,该如何实现呢?
最粗暴的实现是写5个slot,然后将button与slot分别connect,但这明显会增加许多重复代码,不是一种好的实现。
一种比较好的方式是使用QSignalMapper,它可以接收无参数的signal,然后重新发射出有参数的signal,这些参数的类型可以是int、QString、QWidget *或QObject *:

QSignalMapper *signalMapper = new QSignalMapper(this);

connect(button1, SIGNAL(triggered()), signalMapper, SLOT(map()));
connect(button2, SIGNAL(triggered()), signalMapper, SLOT(map()));
connect(button3, SIGNAL(triggered()), signalMapper, SLOT(map()));
connect(button4, SIGNAL(triggered()), signalMapper, SLOT(map()));
connect(button5, SIGNAL(triggered()), signalMapper, SLOT(map()));

signalMapper->setMapping(button1, 1);
signalMapper->setMapping(button2, 2);
signalMapper->setMapping(button3, 3);
signalMapper->setMapping(button4, 4);
signalMapper->setMapping(button5, 5);

connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(printMsg(int)));


然后在printMsg(int)中根据不同的输入参数输出信息即可。

可参考https://stackoverflow.com/questions/5153157/passing-an-argument-to-a-slot

/********************************************************************************
** Form generated from reading UI file 'widget.ui'
**
** Created by: Qt User Interface Compiler version 5.6.0
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/

#ifndef UI_WIDGET_H
#define UI_WIDGET_H

#include <QtCore/QVariant>
#include <QtWidgets/QAction>
#include <QtWidgets/QApplication>
#include <QtWidgets/QButtonGroup>
#include <QtWidgets/QHeaderView>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QWidget>

QT_BEGIN_NAMESPACE

class Ui_Widget
{
public:
    QPushButton *pushButton_1;
    QPushButton *pushButton_2;
    QPushButton *pushButton_3;
    QPushButton *pushButton_4;
    QPushButton *pushButton_5;

    void setupUi(QWidget *Widget)
    {
        if (Widget->objectName().isEmpty())
            Widget->setObjectName(QStringLiteral("Widget"));
        Widget->resize(400, 300);
        pushButton_1 = new QPushButton(Widget);
        pushButton_1->setObjectName(QStringLiteral("pushButton_1"));
        pushButton_1->setGeometry(QRect(50, 30, 75, 23));
        pushButton_2 = new QPushButton(Widget);
        pushButton_2->setObjectName(QStringLiteral("pushButton_2"));
        pushButton_2->setGeometry(QRect(50, 60, 75, 23));
        pushButton_3 = new QPushButton(Widget);
        pushButton_3->setObjectName(QStringLiteral("pushButton_3"));
        pushButton_3->setGeometry(QRect(50, 90, 75, 23));
        pushButton_4 = new QPushButton(Widget);
        pushButton_4->setObjectName(QStringLiteral("pushButton_4"));
        pushButton_4->setGeometry(QRect(50, 120, 75, 23));
        pushButton_5 = new QPushButton(Widget);
        pushButton_5->setObjectName(QStringLiteral("pushButton_5"));
        pushButton_5->setGeometry(QRect(50, 150, 75, 23));

        retranslateUi(Widget);

        QMetaObject::connectSlotsByName(Widget);
    } // setupUi

    void retranslateUi(QWidget *Widget)
    {
        Widget->setWindowTitle(QApplication::translate("Widget", "Widget Title", 0));
        pushButton_1->setText(QApplication::translate("Widget", "PushButton", 0));
        pushButton_2->setText(QApplication::translate("Widget", "PushButton", 0));
        pushButton_3->setText(QApplication::translate("Widget", "PushButton", 0));
        pushButton_4->setText(QApplication::translate("Widget", "PushButton", 0));
        pushButton_5->setText(QApplication::translate("Widget", "PushButton", 0));
    } // retranslateUi

};

namespace Ui {
    class Widget: public Ui_Widget {};
} // namespace Ui

QT_END_NAMESPACE

#endif // UI_WIDGET_H
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

private:
    Ui::Widget *ui;

signals:
    void mapped(int);
private slots:
    void printMsg(int);

};

#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"
#include <QSignalMapper>
#include <QTextStream>
QTextStream out(stdout);

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    QSignalMapper *signalMapper = new QSignalMapper(this);

    connect(this->ui->pushButton_1,SIGNAL(clicked()), signalMapper, SLOT(map()));
    connect(this->ui->pushButton_2,SIGNAL(clicked()), signalMapper, SLOT(map()));
    connect(this->ui->pushButton_3,SIGNAL(clicked()), signalMapper, SLOT(map()));
    connect(this->ui->pushButton_4,SIGNAL(clicked()), signalMapper, SLOT(map()));
    connect(this->ui->pushButton_5,SIGNAL(clicked()), signalMapper, SLOT(map()));

    signalMapper->setMapping(this->ui->pushButton_1, 1);
    signalMapper->setMapping(this->ui->pushButton_2, 2);
    signalMapper->setMapping(this->ui->pushButton_3, 3);
    signalMapper->setMapping(this->ui->pushButton_4, 4);
    signalMapper->setMapping(this->ui->pushButton_5, 5);

    connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(printMsg(int)));


    //然后在printMsg(int)中根据不同的输入参数输出信息即可。

}
void Widget::printMsg(int num)
{
    out<<num<<endl;
    switch(num){
    case 1:
        out<<"Bad!"<<endl;
        break;
    case 2:
        out<<"Not Good!"<<endl;
        break;
    case 3:
        out<<"OK!"<<endl;
        break;
    case 4:
        out<<"Good!"<<endl;
        break;
    case 5:
        out<<"Very Good!"<<endl;
        break;
    default:
        out<<"?????!"<<endl;
        break;
    }
}

Widget::~Widget()
{
    delete ui;
}

 

posted @ 2018-04-12 15:40  sky20080101  阅读(428)  评论(0)    收藏  举报