If you look at In MOC'ed object, you will see there is a signal handler method for each signal which will activate (say execute or send event) the connected slot, this method will be called when you emit a signal, so the emission actually calls a method of that object in thread which is emited. Actually the is signal handler is just another slot. In case of signal to signal connection the signal handler of first object will be called in the calling thread and activates the slot (say signal handler of second object) in connected thread. The activated slot could be a slot of destination object or one of its signals. The activation does care about connection type between the emiter signal and destination slot/signal. When you connect a signal to another signal, actually you're connecting a signal to second object's signal handler.
In DirectConnection the slot will be called in emiter thread.
In QueuedConnection the slot will be called in destination object's thread.
So if you imagine a destination signal as an another slot which emits the destination signal actually we will have:
sig2sig=Direct, sig2slot=Direct
- Connection between SignalA and SignalB is direct, so ObjectB's signal handler will be executed in ObjectA's thread, also connection between SignalB and SlotC is direct, so the SlotC will be executed in emiter thread which is ObjectA's thread
sig2sig=Direct, sig2slot=Queued
- There is direct connection between SignalA and SignalB, ObjectB's signal handler will be executed in ObjectA's thread, but the connection between SignalB and SlotC is queued, so the SlotC will be executed in ObjectC's thread
sig2sig=Queued, sig2slot=Direct
- There is queued connection between SignalA and SignalB, so the emission of SignalA will execute ObjectB's signal handler int ObjectB's thread, now the ObjectB's signal handler will activate the SlotC with Direct scheme, so the SlotC will be executed in its emitter thread which is ObjectB's thread (Thread B).
sig2Sig=Queued, sig2slot=Queued
- There is queued connection between SignalA and SignalB, and also SignalB and SlotC so by emiting SignalA, ObjectB's signal handler will be called in ObjectB's thread (ThreadB) and it emits the SignalB which calls the SlotC in ObjectC's thread (ThreadC)
This code also verifies the behavior
#include <QObject>
#include <QDebug>
#include <QThread>
class XClass : public QObject
{
Q_OBJECT
public:
XClass(char ident){ this->ident=ident; this->moveToThread(&this->t); this->t.start(); }
char ident;
private:
QThread t;
signals:
void signalX();
public slots:
void printTid() { qDebug() << "Object " << this->ident << " lives in thread" << QThread::currentThreadId(); }
void slotX() { qDebug() << "Slot" << this->ident << " fired in thread" << QThread::currentThreadId(); }
void emitSignalX(){ qDebug() << "Signal" << this->ident << "emitng from thread" << QThread::currentThreadId(); emit signalX(); }
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
XClass A('A');
XClass B('B');
XClass C('C');
QMetaObject::invokeMethod(&A, "printTid", Qt::BlockingQueuedConnection);
QMetaObject::invokeMethod(&B, "printTid", Qt::BlockingQueuedConnection);
QMetaObject::invokeMethod(&C, "printTid", Qt::BlockingQueuedConnection);
QObject::connect(&A, &XClass::signalX, &B, &XClass::signalX, Qt::DirectConnection);
QObject::connect(&B, &XClass::signalX, &C, &XClass::slotX, Qt::DirectConnection);
//QObject::connect(&A, &XClass::signalX, &B, &XClass::signalX, Qt::DirectConnection);
//QObject::connect(&B, &XClass::signalX, &C, &XClass::slotX, Qt::QueuedConnection);
//QObject::connect(&A, &XClass::signalX, &B, &XClass::signalX, Qt::DirectConnection);
//QObject::connect(&B, &XClass::signalX, &C, &XClass::slotX, Qt::QueuedConnection);
//QObject::connect(&A, &XClass::signalX, &B, &XClass::signalX, Qt::QueuedConnection);
//QObject::connect(&B, &XClass::signalX, &C, &XClass::slotX, Qt::QueuedConnection);
QMetaObject::invokeMethod(&A, "emitSignalX");
return a.exec();
}
moc
is of no consequence. The behavior is the same. You should also note that there are very few reasons not to use the automatic connection type. – Kuba hasn't forgotten Monica