Qt C++ - How to pass data from a worker thread to main thread?

I am trying to perform interthread communication in Qt (C++). I have a worker thread which does some calculations and I want the workerthread to return its results to the main thread when done. I therefor use a connect, I know thanks to debugging, that the signal is successfully being emit but that it is the slot that isn t being executed and I don t understand why.

The relevant pieces of code:

webcamClass::webcamClass(QObject *parent) : QObject(parent)
{  
    workerThread = new QThread(this);
    workerClassObj = new workerClass();

    //connect for image
    connect(workerClassObj, SIGNAL(mySignal(QPixmap)), this, SLOT(mySlot(QPixmap)));
     //connect(&workerClassObj, workerClass::mySignal(QPixmap), this, webcamClass::mySlot(QPixmap));


    connect( workerThread, SIGNAL(started()), workerClassObj, SLOT(getImage()) );
    workerClassObj->moveToThread(workerThread);


}

void webcamClass:: foo()
{

      workerThread->start();
}

void workerClass::getImage()
{
    qint64 successFailWrite;
    QImage img;
    QPixmap pixmap;

    ... do some stuff with pixmap...

    qDebug()<<"going to emit result";

    emit mySignal(pixmap);

    qDebug()<<"emitted";
}


void webcamClass::mySlot(QPixmap p)
{qDebug()<<"this message should be displayed"; }

The corresponding header files:

   class workerClass : public QObject
    {
        Q_OBJECT
    private:

    public:
        explicit workerClass(QObject *parent = nullptr);


    signals:
        void mySignal(QPixmap);
    };



webcamClass::webcamClass(QObject *parent) : QObject(parent)
{
    Q_OBJECT
public:
    explicit webcamClass(QObject *parent = nullptr);

public slots:
    void mySlot(QPixmap p);

private:

    QThread *workerThread;
    workerClass *workerClassObj;


};

The code above just outputs:

going to emit result
emitted

but unfortunately doesn t output this message should be displayed.

webcamClass belongs to the parent thread, while workerClass belngs to -you guessed it- the worker thread.

Could someone explain how to setup my connect so that mySlot() gets triggered?

Thanks!

Upvotes: 1

Views: 1842

Answers (2)

JLev
JLev

Reputation: 705

In the code you pasted in pastebin.com/UpPfrNEt you have a getVideoFrame method that uses while (1). If this method is called, it runs all the time and blocks the event loop from handling signals. You can solve it in many ways, I think the best practice will be to replace the while(1) with something else.

Upvotes: 1

Hafnernuss
Hafnernuss

Reputation: 2817

If possible, I highly encourage you to use the new Signal Slot syntax:

connect( SOURCEINSTANCE, &CLASS::SIGNAL, TARGETINSTANCE, &CLASS::SLOT );

In your case, that could be:

connect( workerClassObj, &workerClass::mySignal, this, &webcamClass::mySlot );

Specificallyfor your case, if you want to pass Signals and Slots between threads, you have to be careful. First, check the connection type for the connect call, its acutally the last parameter.

connect( workerClassObj, &workerClass::mySignal, this, &webcamClass::mySlot, Qt::QueuedConnection );

For a detailed explanation look here: http://doc.qt.io/qt-5/signalsandslots.html

If you want to pass custom types, you have to declare them as metatypes first. Add e.G. this in your constructor:

qRegisterMetaType("MyDataType");

Please make sure, that your custom datatype has a default constructor and be aware that afaik, references cannot be passed across threads.

Upvotes: 1

Related Questions