title: Event loops and signal-slot processing when using multithreading in Qt
body: <p>I've been having some problems with using <code>QThreads</code> which made me explore different combinations before I've found the right one. However I still don't fully understand what is really happening in the four cases shown below when it comes to event loops and signal-slot processing.</p>
  
  <p>I added some comments to OUTPUT section, but as you can see I'm not sure if my assumptions about what caused observed behaviors are correct. Also I'm not sure if <code>case 3</code> is something that might be used in real code. Here is my test code (only the <code>main.cpp</code> differs for each case):</p>
  
  <blockquote>
    <p>worker.h:</p>
  </blockquote>
  
  <pre><code>#include &lt;QObject&gt;
  #include &lt;QDebug&gt;
  #include &lt;QThread&gt;
  
  class Worker : public QObject
  {
      Q_OBJECT
  public:
      explicit Worker(QObject *parent = 0) { this-&gt;isRunning_ = false;}
      bool isRunning() const { return isRunning_; }
  
  signals:
      void processingFinished();
      void inProgress();
  
  public slots:
      void process()
      {
          this-&gt;isRunning_ = true;
          qDebug() &lt;&lt; this &lt;&lt; "processing started";
          for (int i = 0; i &lt; 5; i++)
          {
              QThread::usleep(1000);
              emit this-&gt;inProgress();
          }
          qDebug() &lt;&lt; this &lt;&lt; "processing finished";
          this-&gt;isRunning_ = false;
          emit this-&gt;processingFinished();
      }
  
  private:
      bool isRunning_;
  };
  </code></pre>
  
  <blockquote>
    <p>workermanager.h:</p>
  </blockquote>
  
  <pre><code>#include "worker.h"
  
  class WorkerManager : public QObject
  {
      Q_OBJECT
  public:
      explicit WorkerManager(QObject *parent = 0) :
          QObject(parent) {}
  
  public slots:
      void process()
      {
          QThread *thread = new QThread();
          Worker  *worker = new Worker();
  
          connect(thread,SIGNAL(started()),worker,SLOT(process()));
          connect(worker,SIGNAL(processingFinished()),this,SLOT(slot1()));
          connect(worker,SIGNAL(inProgress()),this,SLOT(slot2()));
          worker-&gt;moveToThread(thread);
  
          qDebug() &lt;&lt; "starting";
          thread-&gt;start();
          QThread::usleep(500);
          while(worker-&gt;isRunning()) { }
          qDebug() &lt;&lt; "finished";
      }
  
      void slot1() { qDebug() &lt;&lt; "slot1"; }
      void slot2() { qDebug() &lt;&lt; "slot2"; }
  };
  </code></pre>
  
  <blockquote>
    <p>main.cpp (case 1 - no separate thread for <code>workerManager</code>):</p>
  </blockquote>
  
  <pre><code>#include &lt;QCoreApplication&gt;
  #include "workermanager.h"
  
  int main(int argc, char *argv[])
  {
      QCoreApplication a(argc, argv);
  
      WorkerManager* workerManager = new WorkerManager;    
      workerManager-&gt;process();
      qDebug() &lt;&lt; "end";
      return a.exec();
  }
  </code></pre>
  
  <blockquote>
    <p>OUTPUT - both <code>slot1</code> and <code>slot2</code> called at <code>a.exec()</code> (??? - using main event loop?):</p>
  </blockquote>
  
  <pre><code>starting 
  Worker(0x112db20) processing started 
  Worker(0x112db20) processing finished 
  finished 
  end
  slot2 
  slot2 
  slot2 
  slot2 
  slot2 
  slot1 
  </code></pre>
  
  <blockquote>
    <p>main.cpp (case 2 - <code>workerManager</code> moved to separate thread, but thread not started):</p>
  </blockquote>
  
  <pre><code>#include &lt;QCoreApplication&gt;
  #include "workermanager.h"
  
  int main(int argc, char *argv[])
  {
      QCoreApplication a(argc, argv);
  
      WorkerManager* workerManager = new WorkerManager;
      QThread *thread = new QThread();   
      workerManager-&gt;moveToThread(thread);       
      workerManager-&gt;process();
      qDebug() &lt;&lt; "end";
      return a.exec();
  }
  </code></pre>
  
  <blockquote>
    <p>OUTPUT - neither <code>slot1</code> nor <code>slot2</code> was called - (??? event loop associated with thread receives signals but since thread was not started slots are not called?):</p>
  </blockquote>
  
  <pre><code>starting 
  Worker(0x112db20) processing started 
  Worker(0x112db20) processing finished 
  finished 
  end
  </code></pre>
  
  <blockquote>
    <p>main.cpp (case 3 - <code>workerManager</code> moved to separate thread, thread started but <code>workerManager::process()</code> called via <code>workerManager-&gt;process()</code>):</p>
  </blockquote>
  
  <pre><code>#include &lt;QCoreApplication&gt;
  #include "workermanager.h"
  
  int main(int argc, char *argv[])
  {
      QCoreApplication a(argc, argv);
  
      WorkerManager* workerManager = new WorkerManager;
      QThread *thread = new QThread();   
      workerManager-&gt;moveToThread(thread); 
      thread-&gt;start();     
      workerManager-&gt;process();
      qDebug() &lt;&lt; "end";
      return a.exec();
  }
  </code></pre>
  
  <blockquote>
    <p>OUTPUT - <code>slot2</code> called while <code>Worker</code> still executing its <code>process()</code> (???):</p>
  </blockquote>
  
  <pre><code>starting 
  Worker(0x197bb20) processing started 
  slot2 
  slot2 
  slot2 
  slot2 
  Worker(0x197bb20) processing finished 
  finished 
  end 
  slot2 
  slot1 
  </code></pre>
  
  <blockquote>
    <p>main.cpp (case 4 - <code>workerManager</code> moved to separate thread, thread started but <code>workerManager::process()</code> called using <code>started()</code> signal from <code>thread</code>):</p>
  </blockquote>
  
  <pre><code>#include &lt;QCoreApplication&gt;
  #include "workermanager.h"
  
  int main(int argc, char *argv[])
  {
      QCoreApplication a(argc, argv);
  
      WorkerManager* workerManager = new WorkerManager;
      QThread *thread = new QThread();    
      workerManager-&gt;moveToThread(thread);
      QObject::connect(thread,SIGNAL(started()),workerManager,SLOT(process()));
      thread-&gt;start();
      qDebug() &lt;&lt; "end";
      return a.exec();
  }
  </code></pre>
  
  <blockquote>
    <p>OUTPUT - all events processed after reaching <code>a.exec()</code> (???):</p>
  </blockquote>
  
  <pre><code>end 
  starting 
  Worker(0x7f1d700013d0) processing started 
  Worker(0x7f1d700013d0) processing finished 
  finished 
  slot2 
  slot2 
  slot2 
  slot2 
  slot2 
  slot1 
  </code></pre>
  
  <p>Thanks for any clarifications.</p>