Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
quicktestevent.cpp
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "quicktestevent_p.h"
5#include <QtTest/qtestkeyboard.h>
6#include <QtQml/qqml.h>
7#include <QtQuick/qquickitem.h>
8#include <QtQuick/qquickwindow.h>
9#include <qpa/qwindowsysteminterface.h>
10
12
13namespace QTest {
14 extern int Q_TESTLIB_EXPORT defaultMouseDelay();
15}
16
18 : QObject(parent)
19{
20}
21
25
30
31bool QuickTestEvent::keyPress(int key, int modifiers, int delay)
32{
33 QWindow *window = activeWindow();
34 if (!window)
35 return false;
36 QTest::keyPress(window, Qt::Key(key), Qt::KeyboardModifiers(modifiers), delay);
37 return true;
38}
39
40bool QuickTestEvent::keyRelease(int key, int modifiers, int delay)
41{
42 QWindow *window = activeWindow();
43 if (!window)
44 return false;
45 QTest::keyRelease(window, Qt::Key(key), Qt::KeyboardModifiers(modifiers), delay);
46 return true;
47}
48
49bool QuickTestEvent::keyClick(int key, int modifiers, int delay)
50{
51 QWindow *window = activeWindow();
52 if (!window)
53 return false;
54 QTest::keyClick(window, Qt::Key(key), Qt::KeyboardModifiers(modifiers), delay);
55 return true;
56}
57
58bool QuickTestEvent::keyPressChar(const QString &character, int modifiers, int delay)
59{
60 QTEST_ASSERT(character.size() == 1);
61 QWindow *window = activeWindow();
62 if (!window)
63 return false;
64 QTest::keyPress(window, character[0].toLatin1(), Qt::KeyboardModifiers(modifiers), delay);
65 return true;
66}
67
68bool QuickTestEvent::keyReleaseChar(const QString &character, int modifiers, int delay)
69{
70 QTEST_ASSERT(character.size() == 1);
71 QWindow *window = activeWindow();
72 if (!window)
73 return false;
74 QTest::keyRelease(window, character[0].toLatin1(), Qt::KeyboardModifiers(modifiers), delay);
75 return true;
76}
77
78bool QuickTestEvent::keyClickChar(const QString &character, int modifiers, int delay)
79{
80 QTEST_ASSERT(character.size() == 1);
81 QWindow *window = activeWindow();
82 if (!window)
83 return false;
84 QTest::keyClick(window, character[0].toLatin1(), Qt::KeyboardModifiers(modifiers), delay);
85 return true;
86}
87
88#if QT_CONFIG(shortcut)
89// valueToKeySequence() is copied from qquickshortcut.cpp
91{
92 if (value.userType() == QMetaType::Int)
93 return QKeySequence(static_cast<QKeySequence::StandardKey>(value.toInt()));
94 return QKeySequence::fromString(value.toString());
95}
96#endif
97
98bool QuickTestEvent::keySequence(const QVariant &keySequence)
99{
100 QWindow *window = activeWindow();
101 if (!window)
102 return false;
103#if QT_CONFIG(shortcut)
104 QTest::keySequence(window, valueToKeySequence(keySequence));
105#else
106 Q_UNUSED(keySequence);
107#endif
108 return true;
109}
110
111namespace QtQuickTest
112{
114
116
117 // TODO should be Qt::MouseButtons buttons in case multiple buttons are pressed
118 static void mouseEvent(MouseAction action, QWindow *window,
120 Qt::KeyboardModifiers stateKey, const QPointF &_pos, int delay=-1)
121 {
124
125 if (delay == -1 || delay < QTest::defaultMouseDelay())
126 delay = QTest::defaultMouseDelay();
127 if (delay > 0) {
128 QTest::qWait(delay);
129 lastMouseTimestamp += delay;
130 }
131
132 if (action == MouseClick) {
133 mouseEvent(MousePress, window, item, button, stateKey, _pos);
134 mouseEvent(MouseRelease, window, item, button, stateKey, _pos);
135 return;
136 }
137
138 if (action == MouseDoubleClickSequence) {
139 mouseEvent(MousePress, window, item, button, stateKey, _pos);
140 mouseEvent(MouseRelease, window, item, button, stateKey, _pos);
141 mouseEvent(MousePress, window, item, button, stateKey, _pos);
142 mouseEvent(MouseDoubleClick, window, item, button, stateKey, _pos);
143 mouseEvent(MouseRelease, window, item, button, stateKey, _pos);
144 return;
145 }
146
147 QPoint pos = _pos.toPoint();
149 if (sgitem)
150 pos = sgitem->mapToScene(_pos).toPoint();
152 QTEST_ASSERT(stateKey == 0 || stateKey & Qt::KeyboardModifierMask);
153
154 stateKey &= static_cast<unsigned int>(Qt::KeyboardModifierMask);
155
156 QEvent::Type meType;
157 Qt::MouseButton meButton;
158 Qt::MouseButtons meButtons;
159 switch (action)
160 {
161 case MousePress:
163 meButton = button;
164 meButtons = button;
165 break;
166 case MouseRelease:
168 meButton = button;
169 meButtons = Qt::MouseButton();
170 break;
171 case MouseDoubleClick:
173 meButton = button;
174 meButtons = button;
175 break;
176 case MouseMove:
177 meType = QEvent::MouseMove;
178 meButton = Qt::NoButton;
179 meButtons = button;
180 break;
181 default:
182 QTEST_ASSERT(false);
183 }
184 QMouseEvent me(meType, pos, window->mapToGlobal(pos), meButton, meButtons, stateKey);
186 if (action == MouseRelease) // avoid double clicks being generated
187 lastMouseTimestamp += 500;
188
190 if (!qApp->notify(window, &me)) {
191 static const char *mouseActionNames[] =
192 { "MousePress", "MouseRelease", "MouseClick", "MouseDoubleClick", "MouseMove",
193 "MouseDoubleClickSequence" };
194 qWarning("Mouse event \"%s\" not accepted by receiving window",
195 mouseActionNames[static_cast<int>(action)]);
196 }
197 }
198
199#if QT_CONFIG(wheelevent)
200 static void mouseWheel(QWindow* window, QObject* item, Qt::MouseButtons buttons,
201 Qt::KeyboardModifiers stateKey,
202 QPointF _pos, int xDelta, int yDelta, int delay = -1)
203 {
206 if (delay == -1 || delay < QTest::defaultMouseDelay())
207 delay = QTest::defaultMouseDelay();
208 if (delay > 0) {
209 QTest::qWait(delay);
210 lastMouseTimestamp += delay;
211 }
212
213 QPoint pos;
215 if (sgitem)
216 pos = sgitem->mapToScene(_pos).toPoint();
217
218 QTEST_ASSERT(buttons == Qt::NoButton || buttons & Qt::MouseButtonMask);
219 QTEST_ASSERT(stateKey == 0 || stateKey & Qt::KeyboardModifierMask);
220
221 stateKey &= static_cast<unsigned int>(Qt::KeyboardModifierMask);
222 QWheelEvent we(pos, window->mapToGlobal(pos), QPoint(0, 0), QPoint(xDelta, yDelta), buttons,
223 stateKey, Qt::NoScrollPhase, false);
224 we.setTimestamp(++lastMouseTimestamp);
225
227 if (!qApp->notify(window, &we))
228 qWarning("Wheel event not accepted by receiving window");
229 }
230#endif
231};
232
234 (QObject *item, qreal x, qreal y, int button,
235 int modifiers, int delay)
236{
237 QWindow *view = eventWindow(item);
238 if (!view)
239 return false;
240 m_pressedButtons.setFlag(Qt::MouseButton(button), true);
243 Qt::KeyboardModifiers(modifiers),
244 QPointF(x, y), delay);
245 return true;
246}
247
248#if QT_CONFIG(wheelevent)
249bool QuickTestEvent::mouseWheel(
250 QObject *item, qreal x, qreal y, int buttons,
251 int modifiers, int xDelta, int yDelta, int delay)
252{
253 QWindow *view = eventWindow(item);
254 if (!view)
255 return false;
256 QtQuickTest::mouseWheel(view, item, Qt::MouseButtons(buttons),
257 Qt::KeyboardModifiers(modifiers),
258 QPointF(x, y), xDelta, yDelta, delay);
259 return true;
260}
261#endif
262
264 (QObject *item, qreal x, qreal y, int button,
265 int modifiers, int delay)
266{
267 QWindow *view = eventWindow(item);
268 if (!view)
269 return false;
270 m_pressedButtons.setFlag(Qt::MouseButton(button), false);
273 Qt::KeyboardModifiers(modifiers),
274 QPointF(x, y), delay);
275 return true;
276}
277
279 (QObject *item, qreal x, qreal y, int button,
280 int modifiers, int delay)
281{
282 QWindow *view = eventWindow(item);
283 if (!view)
284 return false;
287 Qt::KeyboardModifiers(modifiers),
288 QPointF(x, y), delay);
289 return true;
290}
291
293 (QObject *item, qreal x, qreal y, int button,
294 int modifiers, int delay)
295{
296 QWindow *view = eventWindow(item);
297 if (!view)
298 return false;
301 Qt::KeyboardModifiers(modifiers),
302 QPointF(x, y), delay);
303 return true;
304}
305
307 (QObject *item, qreal x, qreal y, int button,
308 int modifiers, int delay)
309{
310 QWindow *view = eventWindow(item);
311 if (!view)
312 return false;
315 Qt::KeyboardModifiers(modifiers),
316 QPointF(x, y), delay);
317 return true;
318}
319
321 (QObject *item, qreal x, qreal y, int delay, int buttons, int modifiers)
322{
323 QWindow *view = eventWindow(item);
324 if (!view)
325 return false;
326 const Qt::MouseButtons effectiveButtons = buttons ? Qt::MouseButtons(buttons) : m_pressedButtons;
328 Qt::MouseButton(int(effectiveButtons)), Qt::KeyboardModifiers(modifiers),
329 QPointF(x, y), delay);
330 return true;
331}
332
333QWindow *QuickTestEvent::eventWindow(QObject *item)
334{
336 if (window)
337 return window;
338
340 if (quickItem)
341 return quickItem->window();
342
343 QQuickItem *testParentitem = qobject_cast<QQuickItem *>(parent());
344 if (testParentitem)
345 return testParentitem->window();
346 return nullptr;
347}
348
349QWindow *QuickTestEvent::activeWindow()
350{
352 return window;
353 return eventWindow();
354}
355
357 : QObject(testEvent)
358 , m_sequence(QTest::touchEvent(testEvent->eventWindow(item), testEvent->touchDevice()))
359 , m_testEvent(testEvent)
360{
361}
362
364{
365 QWindow *view = m_testEvent->eventWindow(item);
366 if (view) {
367 QPointF pos(x, y);
369 if (quickItem) {
370 pos = quickItem->mapToScene(pos);
371 }
372 m_sequence.press(touchId, pos.toPoint(), view);
373 }
374 return this;
375}
376
378{
379 QWindow *view = m_testEvent->eventWindow(item);
380 if (view) {
381 QPointF pos(x, y);
383 if (quickItem) {
384 pos = quickItem->mapToScene(pos);
385 }
386 m_sequence.move(touchId, pos.toPoint(), view);
387 }
388 return this;
389}
390
392{
393 QWindow *view = m_testEvent->eventWindow(item);
394 if (view) {
395 QPointF pos(x, y);
397 if (quickItem) {
398 pos = quickItem->mapToScene(pos);
399 }
400 m_sequence.release(touchId, pos.toPoint(), view);
401 }
402 return this;
403}
404
406{
407 m_sequence.stationary(touchId);
408 return this;
409}
410
412{
413 m_sequence.commit();
414 return this;
415}
416
423QPointingDevice *QuickTestEvent::touchDevice()
424{
425 static QPointingDevice *device(nullptr);
426
427 if (!device) {
428 device = new QPointingDevice(QLatin1String("test touchscreen"), 42,
432 }
433 return device;
434}
435
448
450
451#include "moc_quicktestevent_p.cpp"
IOBluetoothDevice * device
Type
This enum type defines the valid event types in Qt.
Definition qcoreevent.h:51
@ MouseMove
Definition qcoreevent.h:63
@ MouseButtonPress
Definition qcoreevent.h:60
@ MouseButtonDblClick
Definition qcoreevent.h:62
@ MouseButtonRelease
Definition qcoreevent.h:61
static QWindow * focusWindow()
Returns the QWindow that receives events tied to focus, such as key events.
The QKeySequence class encapsulates a key sequence as used by shortcuts.
static QKeySequence fromString(const QString &str, SequenceFormat format=PortableText)
\inmodule QtGui
Definition qevent.h:196
\inmodule QtCore
Definition qobject.h:103
QObject * parent() const
Returns a pointer to the parent object.
Definition qobject.h:346
\inmodule QtCore\reentrant
Definition qpoint.h:217
\inmodule QtCore\reentrant
Definition qpoint.h:25
void setTimestamp(quint64 timestamp) override
Definition qevent.cpp:338
The QPointingDevice class describes a device from which mouse, touch or tablet events originate.
The QQuickItem class provides the most basic of all visual items in \l {Qt Quick}.
Definition qquickitem.h:63
QQuickTouchEventSequence(QuickTestEvent *testEvent, QObject *item=nullptr)
QObject * release(int touchId, QObject *item, qreal x, qreal y)
QObject * move(int touchId, QObject *item, qreal x, qreal y)
QObject * stationary(int touchId)
QObject * press(int touchId, QObject *item, qreal x, qreal y)
static void setSpontaneous(QEvent *ev)
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
qsizetype size() const noexcept
Returns the number of characters in this string.
Definition qstring.h:186
virtual bool commit(bool processEvents=true)
QTouchEventSequence & move(int touchId, const QPoint &pt, QWindow *window=nullptr)
QTouchEventSequence & press(int touchId, const QPoint &pt, QWindow *window=nullptr)
QTouchEventSequence & release(int touchId, const QPoint &pt, QWindow *window=nullptr)
virtual QTouchEventSequence & stationary(int touchId)
\inmodule QtCore
Definition qvariant.h:65
static void registerInputDevice(const QInputDevice *device)
\inmodule QtGui
Definition qwindow.h:63
QuickTestEvent(QObject *parent=nullptr)
bool mousePress(QObject *item, qreal x, qreal y, int button, int modifiers, int delay)
QQuickTouchEventSequence * touchEvent(QObject *item=nullptr)
Creates a new QQuickTouchEventSequence.
bool mouseDoubleClickSequence(QObject *item, qreal x, qreal y, int button, int modifiers, int delay)
bool mouseMove(QObject *item, qreal x, qreal y, int delay, int buttons, int modifiers)
bool keyRelease(int key, int modifiers, int delay)
bool keyPressChar(const QString &character, int modifiers, int delay)
bool mouseRelease(QObject *item, qreal x, qreal y, int button, int modifiers, int delay)
bool keyReleaseChar(const QString &character, int modifiers, int delay)
~QuickTestEvent() override
bool keyClickChar(const QString &character, int modifiers, int delay)
bool keyClick(int key, int modifiers, int delay)
bool keyPress(int key, int modifiers, int delay)
friend class QQuickTouchEventSequence
bool mouseDoubleClick(QObject *item, qreal x, qreal y, int button, int modifiers, int delay)
bool mouseClick(QObject *item, qreal x, qreal y, int button, int modifiers, int delay)
EGLImageKHR int int EGLuint64KHR * modifiers
QPushButton * button
[2]
Combined button and popup list for selecting options.
int Q_TESTLIB_EXPORT defaultMouseDelay()
static void keyRelease(QWindow *window, char key, Qt::KeyboardModifiers modifier=Qt::NoModifier, int delay=-1)
static void keyPress(QWindow *window, char key, Qt::KeyboardModifiers modifier=Qt::NoModifier, int delay=-1)
static void keyClick(QWindow *window, Qt::Key key, Qt::KeyboardModifiers modifier=Qt::NoModifier, int delay=-1)
Q_CORE_EXPORT void qWait(int ms)
This is an overloaded member function, provided for convenience. It differs from the above function o...
static void mouseEvent(MouseAction action, QWindow *window, QObject *item, Qt::MouseButton button, Qt::KeyboardModifiers stateKey, const QPointF &_pos, int delay=-1)
MouseButton
Definition qnamespace.h:56
@ MouseButtonMask
Definition qnamespace.h:93
@ NoButton
Definition qnamespace.h:57
@ KeyboardModifierMask
@ NoScrollPhase
#define qApp
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define qWarning
Definition qlogging.h:166
GLint GLint GLint GLint GLint x
[0]
GLuint64 key
GLint y
QQuickItem * qobject_cast< QQuickItem * >(QObject *o)
Definition qquickitem.h:492
static QT_BEGIN_NAMESPACE QKeySequence valueToKeySequence(const QVariant &value, const QQuickShortcut *const shortcut)
QLatin1StringView QLatin1String
Definition qstringfwd.h:31
#define QTEST_ASSERT(cond)
Definition qtestassert.h:11
#define Q_UNUSED(x)
double qreal
Definition qtypes.h:187
QWindow * qobject_cast< QWindow * >(QObject *o)
Definition qwindow.h:367
QGraphicsItem * item
aWidget window() -> setWindowTitle("New Window Title")
[2]
QQuickView * view
[0]