Engineer999
Engineer999

Reputation: 3955

Qt : qt cannot send events to objects owned by a different thread - Why

I am developing an application with Qt whereby I want to update my GUI from another unrelated class with functions executing in a different thread.

I registered a callback function from the Qt GUI class to the other class using standard C++ constructs std::function and std::bind.

On trying to execute the GUI callback function from the other class, my program crashes with "qt cannot send events to objects owned by a different thread".

My questions are, what is happening here exactly. Why is it not permissive to communicate between two threads like this. Is it possible to resolve this in some way , or does Qt just not allow other unrelated functions to update the GUI in this way ?

For information , I am using portaudio libraries on windows. It executes a callback in a different thread. When I receive audio, I try to update my GUI.

Thank you in advance

Upvotes: 5

Views: 11532

Answers (1)

You're probably being thrown off by the "send events" phrase. In Qt, this phrase has a strict technical meaning. Namely:

  • to send events means to use QCoreApplication::sendEvent, which then immediately invokes QObject::event on the receiver. It is an error to send events when the sending and receiving threads are different.

  • to post events means to use QCoreApplication::postEvent, which posts the event to the receiving object thread's event queue. The QObject::event on the receiver is invoked later by the receiver thread's event loop.

When objects live in different threads, you're not allowed to send events, only to post them. This points to the underlying cause of your issue/

Any method you access on a QWidget or a derived class must be accessed on its thread(), i.e. the main thread. Everything inside of QWidget can use sendEvent freely as the sending thread and receiving object's thread are identical by contract. By calling QWidget methods from the wrong thread, you break that contract by indirectly using sendEvent and thus fail.

Only methods that you yourself have implemented and are thread-safe can be called from other threads - and they can't use sendEvent.

Upvotes: 7

Related Questions