PDA

View Full Version : Emitting signal from a non-Qt Thread



FreddyKay
29th January 2016, 10:57
Hello people!

What i want to do essentially is send a signal from a non-Qt Thread to a Slot in another Thread.

What I have now is something like this (bit of pseudocode so bear with me):



class CallBackClass : QObject
{
Q_OBJECT
public:
CallBackClass(){ // fancy stuff

notWorkingSignalConnectionClass = new emittingClass();
connect(notWorkingSignalConnectionClass, SIGNAL(dataReady()), this, SLOT(takeData()), Qt::QueuedConnection);//also tried auto connection. same result
}

static int callback(char* field, int len)
{
//other things

notWorkingSignalConnectionClass->setData(field, len);

}

public slots:
void takeData()
{
//i want magic to happen here, but this function is never called
}

private:

static emittingClass* notWorkingSignalConnectionClass;

}





class emittingClass : QObject
{
Q_OBJECT
signals:
void dataReady();

public:
void setData(char* field, int len)
{
//do fancy stuff with field
emit dataReady();
}
}






emittingClass* CallBackClass::notWorkingSignalConnectionClass = new emittingClass();

int main
{
CallBackClass callbackInstance();
//I am starting things here, in particular there is a thread running for handling external data input / output

}




Now what essentially is going on is I have an external library that is handling input / output on a USB device. This library uses its own threads and relies on static callback functions in order to tell me that data is ready. that is the callback() function in the CallBackClass. This function is always called in one particular thread that is different from the main thread in which I actually construct all other objects above.

All the signal slot connections are working fine as long as I am emitting the signal in the same thread, but it is not working when I try to do it from a different thread.

Is there a way to make that work?

anda_skoa
29th January 2016, 11:25
I think in this case it is easier to just call the slot via QMetaObject:.invokeMethod(), i.e. no need for an intermediary "emitter" object.



QMetaObject::invokeMethod(receiver, "takeData", Qt::QueuedConnection);

You can even pass arguments that way.

Cheers,
_

FreddyKay
29th January 2016, 14:55
True, thanks.

Anyway, the problem was at another point of the program entirely and prevented it from starting the even loop in the first place, which is why my signal / slots would not connect. Solved now.