Как мы можем связать сигналы и слот с разными аргументами? - PullRequest
15 голосов
/ 28 октября 2011

В Qt сигналы и слоты требуют соответствия типов аргументов:

QObject :: connect: несовместимые аргументы отправителя / получателя QLabel :: linkActivation (QString) -> Button :: call (int)

Как реализовать такую ​​комбинацию?

Ответы [ 4 ]

34 голосов
/ 28 октября 2011

Из документации по слотам для сигналов :

Подпись сигнала должна совпадать с подписью принимающего слот. (На самом деле слот может иметь более короткую подпись, чем сигнал получает, потому что может игнорировать дополнительные аргументы.)

Это означает, что сигнал вида

signal(int, int, QString)

может быть связано только со слотами со следующими подписями

slot1(int, int, QString)
slot2(int, int)
slot3(int)
slot4()

Как подсказывает Коан, лучше всего использовать другой слот с аргументом QString, а затем вызвать нужный слот.

17 голосов
/ 28 октября 2011

Простой метод состоит в том, чтобы иметь промежуточный слот, который вызывает желаемый слот.например,

connect(src, SIGNAL(linkActivated(QString)), this, SLOT(receiveLink(QString)));

, а затем

void receiveLink(QString blah)
{
  int response = someFunction(blah);
  mybutton->call(response);
}

Вы должны определить некоторый способ интерпретации строки в int.

4 голосов
/ 11 марта 2017

Значения по умолчанию для параметров слота помогают очень хорошо.Это позволяет подключать сигналы с разными сигнатурами к слоту (наоборот, к ответу @pnezis):

private slots:
  void slot( int x = 10, int y = 20, QString text = QString() );

может подключаться к различным сигналам:

signal1(int, int, QString)
signal2(int, int)
signal3(int)
signal4()

Также Qt 4.8предложить полезные QSignalMapper класс:

Этот класс собирает набор сигналов без параметров и повторно генерирует их с целочисленными параметрами, параметрами строки или виджета, соответствующими объекту, который отправил сигнал.

Но только для одного параметра:

QSignalMapper* mapper = new QSignalMapper(this) ;

connect(action, SIGNAL(triggered()), mapper, SLOT(map())) ;
mapper->setMapping(action, "param value") ;

connect(mapper, SIGNAL(mapped(const QString &)),
  this, SIGNAL(clicked(const QString &)));
0 голосов
/ 03 марта 2019

В качестве дополнительного ответа, если вы не хотите писать промежуточный слот, вы можете использовать лямбда-выражения (конечно, с поддержкой C ++ 11) для вызова метода.Однако класс соединителя должен знать типы параметров, используемые в этих конкретных сигналах и слотах.

В качестве примера, предположим, что вы пытаетесь подключить сигнал с типом параметра QString к слотус типом параметра char, вы можете сделать это следующим образом;

class SignalClass{
signals:
    void testSignal(QString tString);
};

class SlotClass{
public slots:
    void testSlot(char tChar);
};

class ConnectorClass{
public:
    void connectSignalAndSlot () {
        SignalClass tSigClass;
        SlotClass tSlotClass;
        connect(&tSigClass, &SignalClass::testSignal,
                [=](QString tString) { this->metaObject()->invokeMethod(tSlotClass,"testSlot", Q_ARG(char, tString.at(0).toLatin1())) }
        );
    }
}

Какая-то уродливая вещь, но делает свою работу.

  • Нет связанных классов
  • Нет функции промежуточного разъема
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...