Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
visualtestutils_p.h
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#ifndef QQUICKVISUALTESTUTILS_P_H
5#define QQUICKVISUALTESTUTILS_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QtGui/private/qguiapplication_p.h>
19#include <QtGui/qpa/qplatformintegration.h>
20#include <QtQml/qqmlexpression.h>
21#include <QtQuick/private/qquickitem_p.h>
22
23#include <private/qmlutils_p.h>
24
25#include <QtCore/qpointer.h>
26
27QT_BEGIN_NAMESPACE
28
29class QQuickItemView;
30class QQuickWindow;
31
33{
34 QQuickItem *findVisibleChild(QQuickItem *parent, const QString &objectName);
35
36 void dumpTree(QQuickItem *parent, int depth = 0);
37
38 void moveMouseAway(QQuickWindow *window);
39 void centerOnScreen(QQuickWindow *window);
40
41 template<typename F>
42 void forEachStep(int steps, F &&func)
43 {
44 if (steps == 1) {
45 // that's odd usage, but cut to the chase then
46 func(qreal(1));
47 return;
48 }
49
50 for (int i = 0; i < steps; ++i) {
51 // - 1 because that gives us {0, 0.5, 1} for progress (if steps == 3),
52 // rather than {0, 0.33, 0.66}.
53 const qreal progress = qreal(i) / (steps - 1);
54 func(progress);
55 }
56 }
57
58 [[nodiscard]] QPoint lerpPoints(const QPoint &point1, const QPoint &point2, qreal t);
59
60 class [[nodiscard]] PointLerper
61 {
62 public:
63 PointLerper(QQuickWindow *window,
64 const QPoint &startingPosition = QPoint(0, 0),
65 const QPointingDevice *pointingDevice = QPointingDevice::primaryPointingDevice());
66
67 void move(const QPoint &pos, int steps = 10, int delayInMilliseconds = 1);
68 void move(int x, int y, int steps = 10, int delayInMilliseconds = 1);
69
70 private:
71 QQuickWindow *mWindow = nullptr;
72 const QPointingDevice *mPointingDevice = nullptr;
73 QPoint mFrom;
74 };
75
76 [[nodiscard]] bool isDelegateVisible(QQuickItem *item);
77
78 /*
79 Find an item with the specified objectName. If index is supplied then the
80 item must also evaluate the {index} expression equal to index
81 */
82 template<typename T>
83 T *findItem(QQuickItem *parent, const QString &objectName, int index = -1)
84 {
85 using namespace Qt::StringLiterals;
86
87 const QMetaObject &mo = T::staticMetaObject;
88 for (int i = 0; i < parent->childItems().size(); ++i) {
89 QQuickItem *item = qobject_cast<QQuickItem*>(parent->childItems().at(i));
90 if (!item)
91 continue;
92 if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
93 if (index != -1) {
94 QQmlContext *context = qmlContext(item);
95 if (!context->isValid())
96 continue;
97 QQmlExpression e(context, item, u"index"_s);
98 if (e.evaluate().toInt() == index)
99 return static_cast<T*>(item);
100 } else {
101 return static_cast<T*>(item);
102 }
103 }
104 item = findItem<T>(item, objectName, index);
105 if (item)
106 return static_cast<T*>(item);
107 }
108
109 return 0;
110 }
111
112 template<typename T>
113 QList<T*> findItems(QQuickItem *parent, const QString &objectName, bool visibleOnly = true)
114 {
115 QList<T*> items;
116 const QMetaObject &mo = T::staticMetaObject;
117 for (int i = 0; i < parent->childItems().size(); ++i) {
118 QQuickItem *item = qobject_cast<QQuickItem*>(parent->childItems().at(i));
119 if (!item || (visibleOnly && (!item->isVisible() || QQuickItemPrivate::get(item)->culled)))
120 continue;
121 if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName))
122 items.append(static_cast<T*>(item));
123 items += findItems<T>(item, objectName);
124 }
125
126 return items;
127 }
128
129 template<typename T>
130 QList<T*> findItems(QQuickItem *parent, const QString &objectName, const QList<int> &indexes)
131 {
132 QList<T*> items;
133 for (int i=0; i<indexes.size(); i++)
134 items << qobject_cast<QQuickItem*>(findItem<T>(parent, objectName, indexes[i]));
135 return items;
136 }
137
138 bool compareImages(const QImage &ia, const QImage &ib, QString *errorMessage);
139
140 struct SignalMultiSpy : public QObject
141 {
143 public:
146
147 template <typename Func1>
150 {
151 return connect(obj, signal, this, &SignalMultiSpy::receive, type);
152 }
153
154 void clear() {
155 senders.clear();
156 signalNames.clear();
157 }
158
159 public Q_SLOTS:
160 void receive() {
162 senders << sender();
163 signalNames << m.name();
164 }
165 };
166
172
173#if QT_CONFIG(quick_itemview)
176#endif
177
178 /*!
179 \internal
180
181 Same as above except allows use in QTRY_* functions without having to call it again
182 afterwards to assign the delegate.
183 */
184 template<typename T>
191
193 {
194 public:
196 const QVariantMap &initialProperties = {},
197 const QStringList &qmlImportPaths = {});
198
199 // Return a C-style string instead of QString because that's what QTest uses for error messages,
200 // so it saves code at the calling site.
201 inline const char *failureMessage() const
202 {
203 return errorMessage.constData();
204 }
205
209
210 bool ready = false;
211 // Store as a byte array so that we can return its raw data safely;
212 // using qPrintable() in failureMessage() will construct a throwaway QByteArray
213 // that is destroyed before the function returns.
215 };
216
218 {
220 public:
222
223 void press(Qt::Key key);
224 void release(Qt::Key key);
225 void click(Qt::Key key);
226
227 private:
228 QPointer<QWindow> m_window;
229 Qt::KeyboardModifiers m_modifiers;
230 };
231
232 QPoint mapCenterToWindow(const QQuickItem *item);
233 QPoint mapToWindow(const QQuickItem *item, qreal relativeX, qreal relativeY);
234 QPoint mapToWindow(const QQuickItem *item, const QPointF &relativePos);
235}
236
237#define SKIP_IF_NO_WINDOW_ACTIVATION do
238 {
239 if (!(QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowActivation)))
240 QSKIP("Window activation is not supported on this platform"); \
241}while (false)
242
243#define SKIP_IF_NO_WINDOW_GRAB do
244 {
245 if (QGuiApplication::platformName() == QLatin1String("minimal"))
246 QSKIP("grabWindow is not supported on the minimal platform"); \
247}while (false)
248
249#define SKIP_IF_NO_MOUSE_HOVER do
250 {
251 if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
252 || (QGuiApplication::platformName() == QLatin1String("minimal")))
253 QSKIP("Mouse hovering is not supported on the offscreen/minimal platforms"); \
254}while (false)
255
256QT_END_NAMESPACE
257
258#endif // QQUICKVISUALTESTUTILS_P_H
void move(const QPoint &pos, int steps=10, int delayInMilliseconds=1)
void move(int x, int y, int steps=10, int delayInMilliseconds=1)
PointLerper(QQuickWindow *window, const QPoint &startingPosition=QPoint(0, 0), const QPointingDevice *pointingDevice=QPointingDevice::primaryPointingDevice())
void centerOnScreen(QQuickWindow *window)
QList< T * > findItems(QQuickItem *parent, const QString &objectName, bool visibleOnly=true)
void dumpTree(QQuickItem *parent, int depth=0)
bool isDelegateVisible(QQuickItem *item)
QPoint mapToWindow(const QQuickItem *item, qreal relativeX, qreal relativeY)
QList< T * > findItems(QQuickItem *parent, const QString &objectName, const QList< int > &indexes)
QPoint mapCenterToWindow(const QQuickItem *item)
QPoint mapToWindow(const QQuickItem *item, const QPointF &relativePos)
QQuickItem * findVisibleChild(QQuickItem *parent, const QString &objectName)
void moveMouseAway(QQuickWindow *window)
bool compareImages(const QImage &ia, const QImage &ib, QString *errorMessage)
T * findItem(QQuickItem *parent, const QString &objectName, int index=-1)
QPoint lerpPoints(const QPoint &point1, const QPoint &point2, qreal t)
void forEachStep(int steps, F &&func)
QMetaObject::Connection connectToSignal(const typename QtPrivate::FunctionPointer< Func1 >::Object *obj, Func1 signal, Qt::ConnectionType type=Qt::AutoConnection)