PDA

View Full Version : Exchange information between non-qt pthreads and gui thread



JohnnyRep
8th March 2011, 09:50
Hi,

I am using Qt for having a nice GUI front-end, while the underlying program doesn't use any QThreads and many objects are not created from the main GUI thread.

There're several PThreads working in the background, which should be able to interact with the GUI. E.g. a module is watching a UDP-Connection and in certain situations it would be nice to signal the GUI to show a dialog to inform the user about it.

My first try was to use a dummy QObject in the PThread to signal the GUI (by using the signals and slots from the dummy object). But it seems lead to a fatal error:
<unknown>: Fatal IO error 11 (Resource temporarily unavailable) on X server :0.0.

What happens to signals in general? Which thread is looking for the event queue?
I guess my assumption, that signals are always handled by the main GUI thread, is wrong.

Btw. is it a problem that my QObject was created from the PThread?

How to solve such a problem in the right way? (without rewriting all modules and porting them to QThreads etc.)

Many thanks for your help!

J.R.

MarekR22
8th March 2011, 11:07
When you mixing frameworks it is a bit more tricky. IMHO safest and the simplest way to call slots from other thread which is not a QThread is to use QMetaObject::invokeMethod with type parameter Qt::QueuedConnection (see Qt::ConnectionType-enum).

For example try something like this:

QMetaObject::invokeMethod(pointerToStateLabel,
"setText",
Qt::QueuedConnection,
Q_ARG(QString, QString("Done"));

Added after 9 minutes:

PS. First try to enforce Qt::QueuedConnection when connecting QObject created in this none-qt thread. Just add this value at the end of each connect (default value is Qt::AutoConnection means auto-determinate kind of connection and this may cause your problems).

wysota
8th March 2011, 11:53
You can use Qt's event system, it is thread-safe. Just use QCoreApplication::postEvent() and handle the event where you need it. You can additionally use event filters.