QSignalMapper

Автор: | 23 июля, 2019

Класс объединяет сигналы от идентифицируемых отправителей. Этот класс собирает набор сигналов без параметров и повторно генерирует их с целочисленными параметрами, параметрами строки или виджета, соответствующими объекту, который отправил сигнал. Класс поддерживает сопоставление определенных строк или целых чисел с конкретными объектами с помощью setMapping(). Затем сигналы объектов могут быть подключены к слоту map(), который будет излучать сигнал mapped() со строкой или целым числом, связанным с исходным объектом сигнализации. Сопоставления могут быть удалены позже с помощью removeMappings ().

Для примера создадим небольшое приложение, которое запускает таймер и присваивает ему личный идентификатор. Через connect() связываем QTimer и  QSignalMapper. При срабатывании таймера сигнал переправляется на QSignalMapper который связывает его с пользовательским идентификатором и вызывает слот crossCapture(int), который подключен к QSignalMapper.

Определение класса

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTimer>
#include <QSignalMapper>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

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

private:
    Ui::Widget *ui;
    int id;

private slots:
    void buttonClick();
    void crossCapture(int);
};

#endif // WIDGET_H

Реализация класса

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget),id(0)
{
    ui->setupUi(this);
    connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(buttonClick()));
}

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


void Widget::buttonClick()
{
    QTimer* timer = new QTimer(this);
    timer->setInterval(5000);
    timer->setSingleShot(true);

    QSignalMapper *  signalMapper = new QSignalMapper(this);

    connect(timer,SIGNAL(timeout()),signalMapper,SLOT( map()));
    signalMapper->setMapping(timer,id++);
    connect(signalMapper,SIGNAL(mapped(int)),this,SLOT(crossCapture(int)));

    ui->textEdit->append(QString("Start timer: %1").arg(id));
    timer->start();

}

void Widget::crossCapture(int i)
{
    ui->textEdit->append(QString("Signal mapper: %1 Stop timer %1").arg(i));
}

При нажатие на кнопку вызывается слот buttonClick(), который создает новый экземпляр QTimer и QSignalMapper. Таймер срабатывает раз 5 секунд, один раз и переходит на переопределенный слот  crossCapture(int i).