def event(self, event): if event.type() != QtCore.QEvent.User: return super().event(event) self.n_events += 1 if self.n_events < self.max_n_events: new_event = QtCore.QEvent(QtCore.QEvent.User) QtCore.QCoreApplication.postEvent(self, new_event) return True
def __init__(self, ms, callable, *args, **kw): super(_FutureCall, self).__init__() # Save the arguments. self._ms = ms self._callable = callable self._args = args self._kw = kw # Save the instance. self._calls_mutex.lock() self._calls.append(self) self._calls_mutex.unlock() # Move to the main GUI thread. self.moveToThread(QtGui.QApplication.instance().thread()) # Post an event to be dispatched on the main GUI thread. Note that # we do not call QTimer.singleShot here, which would be simpler, because # that only works on QThreads. We want regular Python threads to work. event = QtCore.QEvent(self._pyface_event) QtGui.QApplication.postEvent(self, event)
def __init__(self, handler, *args, **kwds): """Initialise the call.""" QtCore.QObject.__init__(self) # Save the details of the call. self._handler = handler self._args = args self._kwds = kwds # Add this to the list. self._calls_mutex.lock() self._calls.append(self) self._calls_mutex.unlock() # Move to the main GUI thread. self.moveToThread(QtGui.QApplication.instance().thread()) # Post an event to be dispatched on the main GUI thread. Note that # we do not call QTimer.singleShot, which would be simpler, because # that only works on QThreads. We want regular Python threads to work. event = QtCore.QEvent(_QT_TRAITS_EVENT) QtGui.QApplication.instance().postEvent(self, event)
def test_qt_process_events_process_all(self): from pyface.qt import QtCore if QtCore.__version_info__ < (5, 0, 0) and is_mac_os: # On Qt4 and OSX, Qt QEventLoop.processEvents says nothing was " # processed even when there are events processed, causing the " # loop to break too soon. (See enthought/traitsui#951)" self.skipTest( "process_cascade_events is not reliable on Qt4 + OSX") is_appveyor = os.environ.get("APPVEYOR", None) is not None if QtCore.__version_info__ <= (5, 12, 6) and is_appveyor: # With Qt + Appveyor, process_cascade_events may # _occasionally_ break out of its loop too early. This is only # seen on Appveyor but has not been reproducible on other Windows # machines (See enthought/traitsui#951) self.skipTest( "process_cascade_events is not reliable on Qt + Appveyor") def cleanup(q_object): q_object.deleteLater() # If the test fails, run process events at least the same # number of times as max_n_events for _ in range(q_object.max_n_events): QtCore.QCoreApplication.processEvents( QtCore.QEventLoop.AllEvents) max_n_events = 10 q_object = DummyQObject(max_n_events=max_n_events) self.addCleanup(cleanup, q_object) QtCore.QCoreApplication.postEvent(q_object, QtCore.QEvent(QtCore.QEvent.User)) # sanity check calling processEvents does not process # cascade of events. QtCore.QCoreApplication.processEvents(QtCore.QEventLoop.AllEvents) self.assertEqual(q_object.n_events, 1) # when process_cascade_events() # then actual = q_object.n_events # If process_cascade_events did not do what it promises, then there # are still pending tasks left. Run process events at least the same # number of times as max_n_events to verify for _ in range(max_n_events): QtCore.QCoreApplication.processEvents(QtCore.QEventLoop.AllEvents) n_left_behind_events = q_object.n_events - actual msg = ( "Expected {max_n_events} events processed on the objects and zero " "events left on the queue after running process_cascade_events. " "Found {actual} processed with {n_left_behind_events} left " "behind.".format( max_n_events=max_n_events, actual=actual, n_left_behind_events=n_left_behind_events, )) self.assertEqual(n_left_behind_events, 0, msg) # If the previous assertion passes but this one fails, that means some # events have gone missing, and that would likely be a problem for the # test setup, not for the process_cascade_events. self.assertEqual(actual, max_n_events, msg)