title: Qt GUI event recording and playback
body: <p>I'm attempting to implement a simple, lightweight system for recording Qt GUI events and playing them back from a script.  I thought this would be fairly straightforward using the magic of Qt's event system, but I'm running into a problem I don't understand.</p>
  
  <p>Here's quick summary of what I'm doing:</p>
  
  <p>RECORDING:</p>
  
  <p>I use <code>QApplication.instance().eventFilter()</code> to capture all GUI events I'm interested in* and save them to a Python script, in which each step looks something like this:</p>
  
  <pre class="lang-py prettyprint-override"><code>obj = get_named_object('MainWindow.my_menubar')
  recorded_event = QMouseEvent(2, PyQt4.QtCore.QPoint(45, 8), 1, Qt.MouseButtons(0x1), Qt.KeyboardModifiers(0x0))
  post_event(obj, recorded_event)
  </code></pre>
  
  <p>PLAYBACK:</p>
  
  <p>I simply execute the script above, in a worker (<strong>non-GUI</strong>) thread.  (I can't use the GUI thread because I want to keep sending scripted events to the application, even if the 'main' eventloop is blocked while a modal dialog eventloop is running.)</p>
  
  <p>The important stuff happens in my <code>post_event()</code> function, which needs to do two things:</p>
  
  <ul>
  <li>First, call <code>QApplication.postEvent(obj, recorded_event)</code></li>
  <li>Wait for all events to finish processing:**
  <ul>
  <li>Post a special event to the same eventloop that <code>obj</code> is running in.</li>
  <li>When the special event is handled:
  <ul>
  <li>Call <code>QApplication.processEvents()</code></li>
  <li>Set a flag that tells the playback thread it's okay to continue</li>
  </ul></li>
  </ul></li>
  </ul>
  
  <p>After the second part is complete, my expectation is that <strong>all effects of the first part (the recorded event) have completed</strong>, since the special event was queued <em>after</em> the recorded event.</p>
  
  <p>The whole system <em>mostly</em> seems to work just fine for mouse events, key events, etc.  But I'm having a problem with <code>QAction</code> handlers when I attempt to playback events for my main <code>QMenuBar</code>.</p>
  
  <p>No matter what I try, it seems that <strong>I can't force my playback thread to block for the completion of all <code>QAction.triggered</code> handlers</strong> that result from clicking on my <code>QMenu</code> items.  As far as I can tell, <code>QApplication.processEvents()</code> is returning <em>before</em> the <code>QAction</code> handler is complete.</p>
  
  <p>Is there something special about <code>QMenu</code> widgets or <code>QAction</code> signals that breaks the normal rules for <code>QApplication.postEvent()</code> and/or <code>QApplication.processEvents()</code>?  <strong>I need a way to block for the completion of my <code>QMenu</code>'s <code>QAction</code> handlers.</strong></p>
  
  <p>[*] Not every event is recorded.  I only record <code>spontaneous()</code> events, and I also filter out a few other types (e.g. <code>Paint</code> events and ordinary mouse movements).</p>
  
  <p>[**] This is important because the next event in the script might refer to a widget that was <em>created</em> by the previous event.</p>