0

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?

Community
  • 1
  • 1
Horst Walter
  • 13,663
  • 32
  • 126
  • 228
  • 1
    The type of connection is based on the thread affinity of the two objects. See http://qt-project.org/doc/qt-4.8/thread-basics.html#qobject-and-threads Are you certain that the correct thread affinity has been established when you make the connection? – RA. Oct 19 '12 at 21:13
  • 1
    Is the event loop of your QThread actually running? If `MyClass::run()` is blocking rather than calling `exec()`, then no event dispatch can happen. Your QThread subclass must pretty much behave like a QApplication; it must let its event loop run naturally. – Nikos C. Oct 19 '12 at 21:13
  • My message loop is no Qt specific message loop, but one for Microsoft FSX (flight simulator). Basically it is something like while(running) { dispatch fsxEvent; sleep(somems) }. Anything I can include to allow the event dispatch? – Horst Walter Oct 19 '12 at 21:18

1 Answers1

2

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.

ololuki
  • 377
  • 1
  • 7
  • 14
hyde
  • 60,639
  • 21
  • 115
  • 176
  • I have tried almost every permutation. MoveToThread, with/without subclassing QThread, connecting before / after starting the thread. Always the same. Communication breakdown after the thread is started. Nevertheless avery good hint and article. – Horst Walter Oct 23 '12 at 16:48
  • 1
    Added stuff about custom event loop to my answer, based on comments under question above. – hyde Oct 23 '12 at 17:03
  • Thanks, I start to get it. Since I have my own loop, Qt's signal/slots are not processed. Updated the original question. Thanks so far for all your efforts, at least having an idea now, where the issue comes from. – Horst Walter Oct 23 '12 at 18:14
  • 1
    This is the root cause and hence the answer to this question. QCoreApplication::processEvents() did not solve the issue, but the further discussion can be found in a rephrased question: http://stackoverflow.com/questions/13054053/qt-how-to-combine-own-message-loop-and-qt-event-loop – Horst Walter Oct 24 '12 at 19:57