def process_cascade_events(): """Process all posted events, and attempt to process new events posted by the processed events. Cautions: - An infinite cascade of events will cause this function to enter an infinite loop. - There still exists technical difficulties with Qt. On Qt4 + OSX, QEventLoop.processEvents may report false saying it had found no events to process even though it actually had processed some. Consequently the internal loop breaks too early such that there are still cascaded events unprocessed. Problems are also observed on Qt5 + Appveyor occasionally. At the very least, events that are already posted prior to calling this function will be processed. See enthought/traitsui#951 """ if ETSConfig.toolkit.startswith("qt"): from pyface.qt import QtCore event_loop = QtCore.QEventLoop() while event_loop.processEvents(QtCore.QEventLoop.ProcessEventsFlag.AllEvents): pass else: from pyface.api import GUI GUI.process_events()
def wait_for_qt_signal(qt_signal, timeout): """ Wait for the given Qt signal to fire, or timeout. A mock implementation of QSignalSpy.wait, which is one of the missing bindings in PySide2, and is not available in Qt4. Parameters ---------- qt_signal : signal Qt signal to wait for timeout : int Timeout in milliseconds, to match Qt API. Raises ------ RuntimeError """ from pyface.qt import QtCore # QEventLoop is used instead of QApplication due to observed # hangs with Qt4. event_loop = QtCore.QEventLoop() def exit(*args, **kwargs): event_loop.quit() timeout_timer = QtCore.QTimer() timeout_timer.setSingleShot(True) timeout_timer.setInterval(timeout) timeout_timer.timeout.connect(exit) qt_signal.connect(exit) timeout_timer.start() event_loop.exec_() qt_signal.disconnect(exit) if timeout_timer.isActive(): timeout_timer.stop() else: raise RuntimeError("Timeout waiting for signal.")