Horst Walter
Horst Walter

Reputation: 14071

Qt Thread object only sending signal as Qt:DirectConnection - why?

I have a class derived from QThread: class MyClass : public QThread This class is connected with a slot of another object. Originally this was connected as Qt::AutoConnection. But then - as soon as the thread is started (MyClass::run()) - the signal is no longer "reaching the slot" (why?).

// connected before myObject->run()
s = QObject::connect(
_myObject, SIGNAL(signalLogMessage(const QString&, QtMsgType)), 
this, SLOT(slotLogMessage(const QString&, QtMsgType)), Qt::DirectConnection);

My first idea was that I need to force Qt::QueuedConnection (this / _myObject will be cross threaded). In this case it does not work at all. Only Qt::DirectConnection works. After the thread is started, IMHO Qt::QueuedConnection is the correct choice (cross thread).

Any idea what is going wrong? The connection itself seems to be correct, otherwise it was not working at (mean even not with Qt::DirectConnection).

Edit 1: -- As of hyde's answer / Nikos' comment

As of right now I think hyde's answer / Nikos' comment are pointing out the root cause. My QThread is running it's own message loop for another application. This is the reason why it is running in its own thread and is basically an infinite loop

run() { 
  // exec(); // while not reached    
  while (_runMessageLoop && ...) {
    hr = CallDispatch(.....);
    if (hr== 0) QThread::msleep(100); 
    // QCoreApplication::processEvents();
  }
}

Guess due to this infinite loop the Qt message loop is not running and no signal / slots are processed (is this correct?) When forcing Qt::DirectConnection the methods are called directly with no Qt message loop required, this might be the reason why this is the only connection type working.

The question is now, how can I combine the Qt and my own message loop (if this is feasible)? Cannot call exec() before the loop (because then it is in the Qt loop), and just the QCoreApplication::processEvents(); in "my loop" is still not working.

=> see new Question here: How to combine own message loop and Qt event loop?

Upvotes: 0

Views: 1333

Answers (1)

hyde
hyde

Reputation: 62777

Hard to say without seeing all the code, but it may be because of this:

QThread object itself is not the thread, it's the thread controller. Most importantly, QThread object's thread affinity should not be the thread it controls. If your thread runs Qt event loop, then it's best to avoid subclassing QThread. Instead, have your logic (inter-thread slots etc) in another QObject, which you move to the thread you created with moveToThread after creating it. Only real reason to subclass QThread is to override run() method with one which does not call exec().

Related reading: https://www.qt.io/blog/2010/06/17/youre-doing-it-wrong

Addition: If you override QThread::run(), you have to call QThread::exec() there or event loop won't be running and no non-direct signal gets delivered to any QObject with that thread affinity. If you want to have your own event loop, that is possible, you just have to call QCoreApplication::processEvents() to process Qt events.

Upvotes: 2

Related Questions