QSignalMapper Class
/************************************************************************************** * QT QSignalMapper * * QSignalMapper可以看做是一个信号的转发类。将多个信号作为一个集合,当接受到信号之后, * 将信号转发出去,并且可以更改发送出去信号参数类型。进行映射之后,接受到信号将会发给 * map()函数,而map()函数又会发送mapped()信号。 * Button是qt中常用到的控件,当使用多个Button时,如果每一个button都对应一个slot函数, * 就会显得很多余,使用QSignalMapper类就能避免这种情况,提高不少效率。 * 参考: * http://doc.qt.io/qt-4.8/qsignalmapper.html#setMapping * http://blog.csdn.net/cuteqt/article/details/4306900 * * Tony Liu, 2016-5-20, Shenzhen **************************************************************************************/ 1. 首先分析参考链接中,QT官网的例子。 class ButtonWidget : public QWidget { Q_OBJECT public: ButtonWidget(QStringList texts, QWidget *parent = 0); slots: void doclicked(const QString &text); private: QSignalMapper *signalMapper; }; ButtonWidget::ButtonWidget(QStringList texts, QWidget *parent) : QWidget(parent) { signalMapper = new QSignalMapper(this); QGridLayout *gridLayout = new QGridLayout; for (int i = 0; i < texts.size(); ++i) { QPushButton *button = new QPushButton(texts[i]); //将信号发送给signalMapper对象的map()函数 connect(button, SIGNAL(clicked()), signalMapper, SLOT(map())); //进行映射,表示当button发送信号给map()函数,map()函数将会发出mapped(texts[i])信号,将texts[i]作为参数 signalMapper->setMapping(button, texts[i]); gridLayout->addWidget(button, i / 3, i % 3); } //发出的mapped()函数,由doclicked()函数接收 connect(signalMapper, SIGNAL(mapped(const QString &)), this, SLOT(doclicked(const QString &))); setLayout(gridLayout); } 2.自己实现 class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private slots: void buttonClicked(QWidget *w); private: Ui::MainWindow *ui; QSignalMapper signalMapper; }; MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); signalMapper.setMapping(ui->pushButton_O_1, ui->pushButton_O_1); signalMapper.setMapping(ui->pushButton_O_2, ui->pushButton_O_2); signalMapper.setMapping(ui->pushButton_O_3, ui->pushButton_O_3); signalMapper.setMapping(ui->pushButton_O_4, ui->pushButton_O_4); signalMapper.setMapping(ui->pushButton_O_5, ui->pushButton_O_5); signalMapper.setMapping(ui->pushButton_O_6, ui->pushButton_O_6); signalMapper.setMapping(ui->pushButton_O_7, ui->pushButton_O_7); signalMapper.setMapping(ui->pushButton_O_8, ui->pushButton_O_8); signalMapper.setMapping(ui->pushButton_O_9, ui->pushButton_O_9); connect(ui->pushButton_O_1, SIGNAL(clicked()), &signalMapper, SLOT(map())); connect(ui->pushButton_O_2, SIGNAL(clicked()), &signalMapper, SLOT(map())); connect(ui->pushButton_O_3, SIGNAL(clicked()), &signalMapper, SLOT(map())); connect(ui->pushButton_O_4, SIGNAL(clicked()), &signalMapper, SLOT(map())); connect(ui->pushButton_O_5, SIGNAL(clicked()), &signalMapper, SLOT(map())); connect(ui->pushButton_O_6, SIGNAL(clicked()), &signalMapper, SLOT(map())); connect(ui->pushButton_O_7, SIGNAL(clicked()), &signalMapper, SLOT(map())); connect(ui->pushButton_O_8, SIGNAL(clicked()), &signalMapper, SLOT(map())); connect(ui->pushButton_O_9, SIGNAL(clicked()), &signalMapper, SLOT(map())); //发送的参数只能使QString和QWidget,QObject等,而QPushButton继承了QWidget connect(&signalMapper, SIGNAL(mapped(QWidget *)), this, SLOT(buttonClicked(QWidget *))); /* 给Button设置一个属性,并给属性添加值,如果一个按键带有多个参数的时候, * 设置属性是个不错的方法,可以设置多个属性 */ ui->pushButton_O_1->setProperty("gpio", 1); ui->pushButton_O_2->setProperty("gpio", 2); ui->pushButton_O_3->setProperty("gpio", 3); ui->pushButton_O_4->setProperty("gpio", 4); ui->pushButton_O_5->setProperty("gpio", 5); ui->pushButton_O_6->setProperty("gpio", 6); ui->pushButton_O_7->setProperty("gpio", 7); ui->pushButton_O_8->setProperty("gpio", 8); ui->pushButton_O_9->setProperty("gpio", 9); } MainWindow::~MainWindow() { ::close(gpio_fd); delete ui; } void MainWindow::buttonClicked(QWidget *w) { //获取属性,传入的参数使qvariant类型的,需要转化为int类型 int gpioIndex = qvariant_cast<int>(w->property("gpio")); QString str = QString::number(gpioIndex, 10); //由于传入的参数使QWidget,如果要设置按键,需要转为QPushButton,才能操作button QString ioState = ((QPushButton *)w)->text(); }