C++ QT: функция, принимающая указатель на функцию сигнала и слота

avatar
Matthias Herrmann
8 апреля 2018 в 08:55
716
2
2

QT 5.1:

Чтобы удалить избыточный код, я хочу передать общую логику на аутсорсинг, следующие два вызова функций содержат:

client.cpp

void Client::connectToSignals()
{
    QObject::connect(Client::mqtt.get(), &QMqttClient::connected, this,
                     &Client::onConnected);
    QObject::connect(Client::mqtt.get(), &QMqttClient::disconnected, this,
                     &Client::onDisconnected);
}

Поэтому Client::mqtt.get() и контекст this всегда остаются одинаковыми. Таким образом, метод должен принимать signal и slot в качестве параметров. Функция slot всегда определяется в client.h.

.

Тело метода новой функции без параметров выглядит следующим образом:

void Client::connectToMqttSignal(){}

Какой тип можно использовать для параметров? Могу ли я указать, что мне нужны только функции Signal из QMqttClient, установив определенный тип без проверки идентификатора типа во время выполнения? И как лучше передать Slot в качестве параметра?

Я читал здесь о сигналах и слотах:

https://doc.qt.io/qt-5/signalsandslots.html

Документация для QMqttCLient

https://doc.qt.io/QtMQTT/index.html

Источник

Ответы (2)

avatar
user3606329
8 апреля 2018 в 09:57
3

Вы можете использовать шаблон для передачи сигналов и слотов в качестве параметров.

template <typename Func1, typename Func2>
static inline QMetaObject::Connection conWrapper(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal,
                                 const typename QtPrivate::FunctionPointer<Func2>::Object *receiver, Func2 slot,
                                 Qt::ConnectionType type = Qt::AutoConnection)
{
    return QObject::connect(sender, signal, receiver, slot, type);
}

Пример использования синтаксиса:

conWrapper(this, &MainWindow::someSignal, this, &MainWindow::someSlot);

Вам просто нужно заменить отправителя на Client::mqtt.get() и получателя на this внутри функции и удалить 2 параметра в соответствии с вашими требованиями.

avatar
Kuba hasn't forgotten Monica
8 апреля 2018 в 20:14
2

Если вы имеете в виду конкретную подпись, она может быть такой простой, как:

QMetaObject::Connection Client::connectMqtt((QMqttClient::*signal)(), 
                                            (Client::*slot)())
{
  return connect(mqtt.get(), signal, this, slot);
}

В противном случае шаблонная версия в другом ответе будет более гибкой.