1
votes

I have a class as follows:

handler.h:

#ifndef HANDLER_H
#define HANDLER_H

#include <QObject>

class handler : public QObject
{
    Q_OBJECT

public:
    explicit handler(QObject *parent = nullptr);
    ~handler();

public slots:
    void returnHandler(int input);
};

#endif // HANDLER_H

handler.cpp:

#include "handler.h"
#include "otherclass.h"

handler::handler(QObject *parent) : QObject(parent)
{

}

handler::~handler()
{

}

void handler::returnHandler(int input)
{
    otherclass *otherclassPointer = otherclass::getInstance();
    otherclassPointer->returnFunction(input);
}

As shown, this is a very simple class, which aims to receive an input and pass the input to a function in an external class ('otherclass'). In my main application ('main.cpp'), I create a QThread, and call the returnHandler slot when the QThread is started, as follows:

main.cpp:

QThread* newThread = new QThread();
handler* handlerPointer = new handler();
handlerPointer->moveToThread(newThread);
connect(newThread, SIGNAL(started()), handlerPointer, SLOT(returnHandler(someInput)));
newThread->start();

The issue I'm having is this:

  • I'm currently get the following error:

    QObject::connect: No such slot handler::returnHandler(someInput) in ../app/main.cpp:100

  • However, if I remove the int input from the handler class (both the .h and .cpp files), the SLOT() is recognized and called successfully when the QThread is started.

Why does adding an argument cause the slot to no longer be recognized?

EDIT: Following some very informative and appreciated comments/answers below, I've modified the approach as follows:

  1. Create a signal in the handler class, which matches the parameters of the returnHandler slot. E.g. void handlerSignal(int).
  2. Used the handlerSignal() SIGNAL instead of the QThread::started() signal in the connect().
  3. Emit the handlerSignal() once the QThread is started.

`

QThread* newThread = new QThread();
handler* handlerPointer = new handler();
handlerPointer->moveToThread(newThread);
connect(handlerPointer, SIGNAL(handlerSignal(int)), handlerPointer, SLOT(returnHandler(int)));
newThread->start();
emit handlerPointer->handlerSignal(someInput);

Thanks!

2
You have to define connection slot in this way: SLOT(returnHandler(int). I.e. you need to provide rather slot's signature instead.vahancho
Be aware, though, that signatures of started and returnHandler do not match with the additional parameter...Aconcagua
You might (if using Qt5) prefer the new syntax: connect(thread, &QThread::started, hp, &Handler::returnHandler);. The new syntax even allows usage of a lambda: connect(thread, &Qthread::started, [&hp, someInput]() { /*...*/ });.Aconcagua
Possible duplicate of Qt: SIGNAL, SLOT Macro declarationJoseph D.

2 Answers

6
votes

Two things:

  1. Qt expects the signal and the slot to have the same parameter types.
  2. In SLOT(), you have to provide types, and not names for the parameters.
    SLOT(returnHandler(int))
    instead of
    SLOT(returnHandler(someInput))
    Qt uses the signals and slots's names and argument list to identify them. I your case, Qt looks for a slot named 'returnHandler' and having only one parameter, from type 'someInput'.
0
votes

connect takes strings as the identification of the signal & slot to connect. The macros SIGNAL and SLOT stringise their arguments (using the preprocessor functionality for that). The argument to SIGNAL or SLOT must therefore be the function name, with parameter types in the parentheses. You cannot do argument binding with them.

If you need to connect to a nullary signal, you need a nullary slot.