File: QtTest.py

package info (click to toggle)
python-anyqt 0.2.0-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 560 kB
  • sloc: python: 4,087; makefile: 192; sh: 3
file content (193 lines) | stat: -rw-r--r-- 6,394 bytes parent folder | download
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())