简体   繁体   中英

Marshal calls to Qt main thread

I'm wrapping libcommuni, which uses Qt, in a different DLL project, which doesn't use Qt. As far as I've been able to tell, I need to run the Qt message pump (via QCoreApplication ) to make sure networking, signals, etc. work properly. However, I'm running in to some problems figuring out how to do just that.

Basically, I want to spin up a thread in the DLL, which calls QCoreApplication::exec() and pumps all the Qt events. I then want to marshal external calls to the DLL, which are on a different thread, to the Qt main thread, so I can safely use libcommuni.

It looks like the recommended approach is to use signals and slots for this, but I've been unable to get that to work. I create a signal on the QObject class that is called via the DLL and I connect it to a slot on the QThread that runs the Qt message pump. However, if I specify Qt::QueuedConnection when connecting the signal and slot, the message is never delivered when I emit the signal. If I omit Qt::QueuedConnection altogether, the slot is called immediately on the calling thread rather than the Qt main thread.

I've also tried explicitly calling QCoreApplication::postEvent() on the DLL thread to send an event to the Qt main thread, but event(QEvent) is never called in the target QThread .

Any ideas on what I'm doing wrong here? I'm guessing I'm not quite understanding Qt's threading model.

When you use QObject::connect without specifying connection type - it uses Qt::AutoConnection , which turns into Qt::DirectConnection if the signal and slot are in a single thread, or into Qt::QueuedConnection , if they are in different threads. So, in your case, I can say, that for the moment, when you connect your signal with your slot, the objects, they belong to, are located in one thread.

In order to make Qt::QueuedConnection work, you need an event loop in a thread, which contains slot.

There are two main ways of using QThread:

  1. You can derive QThread and rewrite QThread::run . In that case you should do several things:

    • When creating your thread's object, do not specify parent; remove this object manually.
    • In your thread's constructor call moveToThread(this) .
    • In your thread's run method call exec after all initialization, but before all removal; thread will leave exec right after you call QThread::quit .
  2. You can derive QObject , create QThread object, and call QThread::moveToThread on your object (which, by the way, should be created without specifying parent) before calling QThread::start .

In your case I would recommend using the second method.

That is about threads, but I am not quite sure, your problem isn't connected with QCoreApplication::exec .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM