Qt documentation states that signals and slots can be direct, queued and auto.
Cross Thread Signals and Slots. At emit time Qt compares thread ids. The id of the current thread calling emit signal. The id the receiver belongs to via obj-thread. If the threads are the same slots are called. If different an event is packaged/posted 47. Cross-thread signal-slot connections are implemented by dispatching a QMetaCallEvent to the target object.
It also stated that if object that owns slot ‘lives’ in a thread different from object that owns signal, emitting such signal will be like posting message – signal emit will return instantly and slot method will be called in target thread’s event loop.
Unfortunately, documentation do not specify that ‘lives’ stands for and no examples is available. I have tried the following code:
main.h:

main.cpp:
Output is:
MySlot() is never called :(. What I’m doing wrong?
There are quite a few problems with your code :
This code would most likely work (though I have not tested it) and I think it does what you want it to do :
Now MyObject will live in thread2 (thanks to moveToThread).
MySignal should be sent from thread1 (thought I’m not sure on that one, it might be sent from main thread, it doesn’t really matter).
No event loop is needed in thread1 since emitting a signal doesn’t need an event loop. An event loop is needed in thread2 (lanched by exec()) to receive the signal.
MySlot will be called in thread2.
While Aiua’s answer is good, I want to point out some issues with QThread and Qt 4.6 or 4.7.
This article sums it up: http://blog.qt.io/blog/2010/06/17/youre-doing-it-wrong/
Unfortunately the problem stems from a lack of updates to documentation. Prior to Qt 4.4 QThread had no default run() implementation, which meant that you had to subclass QThread in order to use it.
If you’re using Qt 4.6 or 4.7 then you almost certainly should not subclass QThread.
The key to getting slots to execute in a worker thread is to use the moveToThread method as Aiua pointed out.
Tags: qt
A few notes that are already mentioned in the official docs here and here:
moveToThread from the thread where the object is currently living inQThread is a handle to a platform thread. It lets you manage the thread by monitoring its lifetime, and requesting that it finishes its work.
In most cases inhering from the class is not recommended. The default run method starts an event loop that can dispatch events to objects living in the class. Cross-thread signal-slot connections are implemented by dispatching a QMetaCallEvent to the target object.
A QObject instance can be moved to a thread, where it will process its events, such as timer events or slot/method calls.
To do work on a thread, first create your own worker class that derives from QObject. Then move it to the thread. The object can run its own code automatically e.g. by using QMetaObject::invokeMethod().
If your worker should be ephemeral and only exist while its work is being done, it's best to submit a functor or a thread-safe method for execution in the thread pool via QtConcurrent::run.
If you find managing QThreads and low-level primitives like mutexes or semaphores too complex, Qt Concurrent namespace is what you are looking for. It includes classes which allow more high-level thread management.
Let's look at Concurrent Run. QtConcurrent::run() allows to run function in a new thread. When would you like to use it? When you have some long operation and you don't want to create thread manually.
Now the code:
So things are simple: when we need to run another function in another thread, just call QtConcurrent::run, pass function and its parameters and that's it!
QFuture presents the result of our asynchronous computation. In case of QtConcurrent::run we can't cancel the function execution.
When a Qt event loop is used to perform operations and a non-Qt-saavy user needs to interact with that event loop, writing the slot to handle regular invocations from another thread can simplify things for other users.
main.cpp:
OperationExecutioner.h:
OperationExecutioner.cpp:

OperationExecutioner.pro: