def _QTest_qWaitForWindowActive(widget, timeout=1000): # A Qt5 compatible (probably) QTest.qWaitForWindowActive(QWidget, int) # (mostly copied from qtestsystem.h in qt5/qtbase) from AnyQt.QtCore import \ Qt, QCoreApplication, QEventLoop, QElapsedTimer, QEvent window = widget.window() timer = QElapsedTimer() timer.start() while not window.isActiveWindow(): remaining = timeout - timer.elapsed() if remaining <= 0: break QCoreApplication.processEvents(QEventLoop.AllEvents, remaining) QCoreApplication.sendPostedEvents(None, QEvent.DeferredDelete) QTest.qSleep(10) # See the explanation in qtestsystem.h if window.isActiveWindow(): wait_no = 0 while window.pos().isNull(): if wait_no > timeout // 10: break wait_no += 1 QTest.qWait(10) return window.isActiveWindow()
def test_threadsafe(self): output = OutputView() output.resize(500, 300) output.show() blue_formater = output.formated(color=Qt.blue) red_formater = output.formated(color=Qt.red) correct = [] def check_thread(*args): correct.append(QThread.currentThread() == self.app.thread()) blue = TextStream() blue.stream.connect(blue_formater.write) blue.stream.connect(check_thread) red = TextStream() red.stream.connect(red_formater.write) red.stream.connect(check_thread) def printer(i): if i % 12 == 0: fizzbuz = "fizzbuz" elif i % 4 == 0: fizzbuz = "buz" elif i % 3 == 0: fizzbuz = "fizz" else: fizzbuz = str(i) if i % 2: writer = blue else: writer = red writer.write("Greetings from thread {0}. " "This is {1}\n".format(current_thread().name, fizzbuz)) pool = multiprocessing.pool.ThreadPool(100) res = pool.map_async(printer, range(10000)) self.app.exec_() res.wait() # force all pending enqueued emits QCoreApplication.sendPostedEvents(blue, QEvent.MetaCall) QCoreApplication.sendPostedEvents(red, QEvent.MetaCall) self.app.processEvents() self.assertTrue(all(correct)) self.assertEqual(len(correct), 10000)
def flush(self): """ Flush all pending signal emits currently enqueued. Must only ever be called from the thread this object lives in (:func:`QObject.thread()`). """ if QThread.currentThread() is not self.thread(): raise RuntimeError("`flush()` called from a wrong thread.") # NOTE: QEvent.MetaCall is the event implementing the # `Qt.QueuedConnection` method invocation. QCoreApplication.sendPostedEvents(self, QEvent.MetaCall)
def test_threadsafe(self): output = OutputView() output.resize(500, 300) output.show() blue_formater = output.formatted(color=Qt.blue) red_formater = output.formatted(color=Qt.red) correct = [] def check_thread(*args): correct.append(QThread.currentThread() == self.app.thread()) blue = TextStream() blue.stream.connect(blue_formater.write) blue.stream.connect(check_thread) red = TextStream() red.stream.connect(red_formater.write) red.stream.connect(check_thread) def printer(i): if i % 12 == 0: fizzbuz = "fizzbuz" elif i % 4 == 0: fizzbuz = "buz" elif i % 3 == 0: fizzbuz = "fizz" else: fizzbuz = str(i) if i % 2: writer = blue else: writer = red writer.write("Greetings from thread {0}. " "This is {1}\n".format(current_thread().name, fizzbuz)) pool = multiprocessing.pool.ThreadPool(100) res = pool.map_async(printer, range(10000)) self.qWait() res.wait() # force all pending enqueued emits QCoreApplication.sendPostedEvents(blue, QEvent.MetaCall) QCoreApplication.sendPostedEvents(red, QEvent.MetaCall) self.app.processEvents() self.assertTrue(all(correct)) self.assertEqual(len(correct), 10000) pool.close()
def _QTest_qWait(timeout): from AnyQt.QtCore import Qt, QCoreApplication, QEvent, QEventLoop, QDeadlineTimer remaining = timeout deadline = QDeadlineTimer(remaining, Qt.PreciseTimer) while True: QCoreApplication.processEvents(QEventLoop.AllEvents, remaining) QCoreApplication.sendPostedEvents(None, QEvent.DeferredDelete) remaining = deadline.remainingTime() if remaining <= 0: break QTest.qSleep(min(10, remaining)) remaining = deadline.remainingTime() if remaining <= 0: break
def _QTest_qWaitFor(predicate, timeout=5000): # type: (Callable[[], bool], int) -> bool # Copied and adapted from Qt from AnyQt.QtCore import Qt, QCoreApplication, QEvent, QEventLoop, QDeadlineTimer if predicate(): return True deadline = QDeadlineTimer(Qt.PreciseTimer) deadline.setRemainingTime(timeout) while True: QCoreApplication.processEvents(QEventLoop.AllEvents) QCoreApplication.sendPostedEvents(None, QEvent.DeferredDelete) if predicate(): return True remaining = deadline.remainingTime() if remaining > 0: QTest.qSleep(min(10, remaining)) remaining = deadline.remainingTime() if remaining <= 0: break return predicate() # Last chance
def _QTest_qWaitForWindowExposed(widget, timeout=1000): # A Qt5 compatible (probably) QTest.qWaitForWindowExposed(QWidget, int) # (mostly copied from qtestsystem.h in qt5/qtbase) from AnyQt.QtCore import \ Qt, QCoreApplication, QEventLoop, QElapsedTimer, QEvent window = widget.window() timer = QElapsedTimer() timer.start() # Is widget.testAttribute(Qt.WA_Mapped) a suitable replacement for # QWindow.isExposed in Qt5?? # Not exactly. In Qt5 # window().testAttribute(Qt.WA_Mapped) == window().windowHandle.isExposed() # but both are False if a window is fully obscured by other windows, # in Qt4 there is no difference if a window is obscured. while not window.testAttribute(Qt.WA_Mapped): remaining = timeout - timer.elapsed() if remaining <= 0: break QCoreApplication.processEvents(QEventLoop.AllEvents, remaining) QCoreApplication.sendPostedEvents(None, QEvent.DeferredDelete) QTest.qSleep(10) return window.testAttribute(Qt.WA_Mapped)
def flush(self): """ Flush all pending signal emits currently enqueued. """ assert QThread.currentThread() is self.thread() QCoreApplication.sendPostedEvents(self, QEvent.MetaCall)
def delete_qobject(obj): obj.deleteLater() QCoreApplication.sendPostedEvents(obj, QEvent.DeferredDelete)
def delete(qobj: QObject): assert qobj.thread() is QThread.currentThread() spy = QSignalSpy(qobj.destroyed) qobj.deleteLater() QCoreApplication.sendPostedEvents(qobj, QEvent.DeferredDelete) assert len(spy) == 1