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
Exemple #2
0
    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)
Exemple #3
0
    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)