1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
|
from . import _api
if _api.USED_API == _api.QT_API_PYQT6:
from PyQt6.QtTest import *
elif _api.USED_API == _api.QT_API_PYQT5:
from PyQt5.QtTest import *
elif _api.USED_API == _api.QT_API_PYQT4:
from PyQt4.QtTest import *
elif _api.USED_API == _api.QT_API_PYSIDE:
from PySide.QtTest import *
elif _api.USED_API == _api.QT_API_PYSIDE2:
from PySide2.QtTest import *
def _QTest_qSleep(ms: int):
import time
time.sleep(ms / 1000)
if not hasattr(QTest, "qSleep"):
QTest.qSleep = _QTest_qSleep
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)
if not hasattr(QTest, "qWaitForWindowExposed"):
QTest.qWaitForWindowExposed = _QTest_qWaitForWindowExposed
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()
if not hasattr(QTest, "qWaitForWindowActive"):
QTest.qWaitForWindowActive = _QTest_qWaitForWindowActive
if _api.USED_API in {_api.QT_API_PYQT4, _api.QT_API_PYSIDE, _api.QT_API_PYSIDE2}:
from AnyQt.QtCore import QObject, QByteArray as _QByteArray
# not exposed in PyQt4 or PySide. Going by PyQt5 interface
class QSignalSpy(QObject):
"""
QSignalSpy(boundsignal)
"""
def __init__(self, boundsig, **kwargs):
super(QSignalSpy, self).__init__(**kwargs)
from AnyQt.QtCore import QEventLoop, QTimer
self.__boundsig = boundsig
self.__recorded = recorded = [] # type: List[List[Any]]
self.__loop = loop = QEventLoop()
self.__timer = QTimer(self, singleShot=True)
self.__timer.timeout.connect(self.__loop.quit)
def record(*args):
# Record the emitted arguments and quit the loop if running.
# NOTE: not capturing self from parent scope
recorded.append(list(args))
if loop.isRunning():
loop.quit()
# Need to keep reference at least for PyQt4 4.11.4, sip 4.16.9 on
# python 3.4 (if the signal is emitted during gc collection, and
# the boundsignal is a QObject.destroyed signal).
self.__record = record
boundsig.connect(record)
def signal(self):
return _QByteArray(self.__boundsig.signal[1:].encode("latin-1"))
def isValid(self):
return True
def wait(self, timeout=5000):
count = len(self)
self.__timer.stop()
self.__timer.setInterval(timeout)
self.__timer.start()
self.__loop.exec_()
self.__timer.stop()
return len(self) != count
def __getitem__(self, index):
return self.__recorded[index]
def __setitem__(self, index, value):
self.__recorded.__setitem__(index, value)
def __delitem__(self, index):
self.__recorded.__delitem__(index)
def __len__(self):
return len(self.__recorded)
del QObject
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
if not hasattr(QTest, "qWaitFor"): # Qt < 5.10
QTest.qWaitFor = _QTest_qWaitFor
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
if not hasattr(QTest, "qWait"): # PySide2
QTest.qWait = _QTest_qWait
_api.apply_global_fixes(globals())
|