QThread - multi threaded signals and slots
Hi,
I am trying to figure out how to emit a signal from one my threads to another thread, both non-gui threads. I see in the Qt documentation it is possible, I just cannot figure it out.
Seems like I need something like, I am just not sure in the NetReceive class.
connect(this, SIGNAL(checkNetQueue()), <ptr to other thread>, SLOT(processNetQueue()), Qt::QueuedConnection);
Here is a little background on how my classes are setup:
NetworkThread is a abstract parent class and I have two children from that thread, NetThread and NetReceiveThread. I want NetReceiveThread to emit a signal to the NetThread. If I emit the signal from NetThread itself, the slot executes and works fine.
The threads are created in my Main GUI window as class variables, like NetThread t1, NetReceiveThread t2. And then start() is called on each of them inside the MainWin constructor.
Any ideas you can come up? I appreciate the help.
Thanks so much.
RishiD
---------------------------------------------------------------------
Here are some small snippets of my three thread headers.
NetworkThread.h
Code:
class NetworkThread
: public QThread{
Q_OBJECT
public:
NetworkThread() { };
signals:
void checkNetQueue();
};
NetThread.h
Code:
class NetThread : public NetworkThread
{
Q_OBJECT
public:
NetThread();
protected:
void run()
{
// emitting checkNetQueue() works fine, if the emit is run inside the NetThread
connect(this, SIGNAL(checkNetQueue()), this, SLOT(processNetQueue()));
exec();
}
private slots:
void processNetQueue();
}
NetReceiveThread.h
Code:
class NetReceiveThread : public NetworkThread
{
Q_OBJECT
public:
NetReceiveThread(){}
protected:
void run()
{
// need to change the second this, to a pointer to NetThread
// connect(this, SIGNAL(checkNetQueue()), this, SLOT(processNetQueue()),
// Qt::QueuedConnection);
receiveLoop() // <--- calls emit checkNetQueue();
}
};
Re: QThread - multi threaded signals and slots
Make
Code:
connect(this, SIGNAL(checkNetQueue()), this, SLOT(processNetQueue()));
use direct connection instead:
Code:
connect(this, SIGNAL(checkNetQueue()), this, SLOT(processNetQueue()), Qt::DirectConnection);
Otherwise the signal gets queued and processNextQueue() gets called in "wrong" thread context (because QThread lives in the creator thread, which is not same as QThread::run()).
Re: QThread - multi threaded signals and slots
Ok, that will fix that problem I was having where the QThread was actually calling the processNetQueue() which I did not want. I wanted the NetThread instance to take care of it.
But for the receive thread, should I used a Queued connection or Direct? Right now it is working with Queued, but once again QThread is calling the slot. I am assuming I should change this to Direct?
The code below is how I have it in the receive thread run() method. Where netThread is a pointer to the NetThread object that is created in the MainWin.
Thanks for the help, once again jpn.
Code:
connect(this, SIGNAL(checkNetQueue()), netThread,
SLOT(processNetQueue()), Qt::QueuedConnection);
Re: QThread - multi threaded signals and slots
There's the problem. Slots in QThread subclasses are very problematic. QThread object itself lives in different thread than QThread::run() is executed. Slots get called in the thread context where the receiver QObject lives. You can't fix it by changing connection type. I recommend you don't do anything else but allocate an object with required slots on the stack and call exec() in QThread::run(). This object will live in the worker thread and receive signals like you want.
Code:
{
...
void run()
{
Receiver recv; // <-- this object lives in the worker thread and receives signals "correctly"
...
exec();
}
...
}
Re: QThread - multi threaded signals and slots
Alright that does make sense. Time to restructure all my objects and threads, will report back if I have any problems.
Thanks