Search code examples
qtsignals-slotsqthread

No matching call to connect - when I set 7 parameters. works fine with 6 parameters


Is there a restriction on number of parameters of signals?

/home/.../testerslow/jjjj.h:36: error: no matching function for call to 'Controller::connect(Controller* const, void (Controller::*)(int, int, int, int, int, int, int), Worker*&, void (Worker::*)(int, int, int, int, int, int, int))'
         connect (this, &Controller::operate, worker, &Worker::doWork);

In the following code, just reduce 1 parameter to the signal slot dowork and operate and the error will vanish.

What's the way to pass 7th argument?

Reproducable example:

#ifndef JJJJ
#define JJJJ
#include <QQuickItem>
#include <QDebug>
#include <QThread>


class Worker : public QObject
{
    Q_OBJECT

public:
    Worker() { }

public slots:
    void doWork (int one, int b, int c, int d, int e, int f, int h)
    {
        emit resultReady("");
    }

signals:
    void resultReady(const QString &result);
};

class Controller : public QObject
{
    Q_OBJECT

    QThread workerThread;

public:
    Controller() {
        Worker *worker = new Worker;

        connect (&workerThread, &QThread::finished, worker, &QObject::deleteLater);
        connect (this, &Controller::operate, worker, &Worker::doWork);
        connect (worker, &Worker::resultReady, this, &Controller::handleResults);
        worker->moveToThread(&workerThread);

        workerThread.start();
    }

    ~Controller() {
        workerThread.quit();
        workerThread.wait();
    }

public slots:
    void handleResults(const QString &) {}

signals:
    void operate(int, int, int,int,int,int, int);
};
#endif // JJJJ

Solution

  • According to the documentation, you are limited to calls with six arguments or less using new-style syntax unless your compiler supports variadic template signatures. A quick solution is to create a container type and register it with QMetaType using Q_DECLARE_METATYPE and qRegisterMetaType.

    First, declare the data type:

    //foo.h
    #include <QMetaType>
    
    struct Foo 
    {
        int one, b, c, d, e, f, h;
    }
    Q_DECLARE_METATYPE(Foo)
    

    Since you're using threads, which means queued signals, you also need to register the metatype at runtime with qRegisterMetaType, usually in main or some initialization function that is only called once:

    //main.cpp
    #include <QApplication>
    #include <QMetaType>
    #include "foo.h"
    
    int main(...)
    {
        QApplication app(argc, argv);
        qRegisterMetaType<Foo>();
        ... //do more things here
        return app.exec()
    }
    

    You should now be able to use Foo in signal and slot connections without issue using the following for your signal and slot signatures:

    void doWork(Foo foo);
    

    and

    void operate(Foo);