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
qquickwidget.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 "qquickwidget.h"
5#include "qquickwidget_p.h"
7#include <QtWidgets/private/qwidgetrepaintmanager_p.h>
8
9#include "private/qquickwindow_p.h"
10#include "private/qquickitem_p.h"
11#include "private/qquickitemchangelistener_p.h"
12#include "private/qquickrendercontrol_p.h"
13#include "private/qsgrhisupport_p.h"
14
15#include "private/qsgsoftwarerenderer_p.h"
16
17#include <private/qqmldebugconnector_p.h>
18#include <private/qquickprofiler_p.h>
19#include <private/qqmldebugserviceinterfaces_p.h>
20
21#include <QtQml/qqmlengine.h>
22#include <private/qqmlengine_p.h>
23#include <QtCore/qbasictimer.h>
24#include <QtGui/QOffscreenSurface>
25#include <QtGui/private/qguiapplication_p.h>
26#include <QtGui/qpa/qplatformintegration.h>
27
28#include <QtGui/QPainter>
29
30#include <QtQuick/QSGRendererInterface>
31
32#ifdef Q_OS_WIN
33#if QT_CONFIG(messagebox)
34# include <QtWidgets/QMessageBox>
35#endif
36# include <QtCore/QLibraryInfo>
37# include <QtCore/qt_windows.h>
38#endif
39
40#include <QtQuick/qquickgraphicsdevice.h>
41#include <QtQuick/qquickrendertarget.h>
42
43#include "private/qwidget_p.h"
44
45#if QT_CONFIG(graphicsview)
46#include <QtWidgets/qgraphicsscene.h>
47#include <QtWidgets/qgraphicsview.h>
48#endif
49
50#if QT_CONFIG(vulkan)
51#include <QtGui/private/qvulkandefaultinstance_p.h>
52#endif
53
55
62
63// override setVisble to prevent accidental offscreen window being created
64// by base class.
66public:
67 void setVisible(bool visible) override {
68 Q_Q(QWindow);
69 // this stays always invisible
70 visibility = visible ? QWindow::Windowed : QWindow::Hidden;
71 q->visibilityChanged(visibility); // workaround for QTBUG-49054
72 }
73};
74
76
78{
79 Q_DECLARE_PRIVATE(QQuickWidgetRenderControl)
80public:
83
84};
85
87{
88public:
89 Q_DECLARE_PUBLIC(QQuickWidgetRenderControl)
95
96 bool isRenderWindow(const QWindow *w) override {
97#if QT_CONFIG(graphicsview)
99 auto *proxy = (widgetd && widgetd->extra) ? widgetd->extra->proxyWidget : nullptr;
100 auto *scene = proxy ? proxy->scene() : nullptr;
101 if (scene) {
102 for (const auto &view : scene->views()) {
103 if (view->window()->windowHandle() == w)
104 return true;
105 }
106 }
107
108 return m_quickWidget->window()->windowHandle() == w;
109#endif
110 }
112};
113
118
120{
122 if (offset)
123 *offset = d->m_quickWidget->mapTo(d->m_quickWidget->window(), QPoint());
124
125 QWindow *result = nullptr;
126#if QT_CONFIG(graphicsview)
127 QWidgetPrivate *widgetd = QWidgetPrivate::get(d->m_quickWidget);
128 if (widgetd->extra) {
129 if (auto proxy = widgetd->extra->proxyWidget) {
130 auto scene = proxy->scene();
131 if (scene) {
132 const auto views = scene->views();
133 if (!views.isEmpty()) {
134 // Get the first QGV containing the proxy. Not ideal, but the callers
135 // of this function aren't prepared to handle more than one render window.
136 auto candidateView = views.first();
137 result = candidateView->window()->windowHandle();
138 }
139 }
140 }
141 }
142#endif
143 if (!result)
144 result = d->m_quickWidget->window()->windowHandle();
145
146 return result;
147}
148
150{
151 Q_Q(QQuickWidget);
152
154 offscreenWindow->setScreen(q->screen());
155 // Do not call create() on offscreenWindow.
156
157 QWidget::connect(offscreenWindow, SIGNAL(sceneGraphInitialized()), q, SLOT(createFramebufferObject()));
158 QWidget::connect(offscreenWindow, SIGNAL(sceneGraphInvalidated()), q, SLOT(destroyFramebufferObject()));
159 QWidget::connect(offscreenWindow, &QQuickWindow::focusObjectChanged, q, &QQuickWidget::propagateFocusObjectChanged);
160
161#if QT_CONFIG(accessibility)
162 QAccessible::installFactory(&qAccessibleQuickWidgetFactory);
163#endif
164}
165
167{
168 // This should initialize, if not already done, the absolute minimum set of
169 // mandatory backing resources, meaning the QQuickWindow and its
170 // QQuickRenderControl. This function may be called very early on upon
171 // construction, including before init() even.
172
173 Q_Q(QQuickWidget);
174 if (!renderControl)
176 if (!offscreenWindow)
178
179 // Check if the Software Adaptation is being used
180 auto sgRendererInterface = offscreenWindow->rendererInterface();
181 if (sgRendererInterface && sgRendererInterface->graphicsApi() == QSGRendererInterface::Software)
182 useSoftwareRenderer = true;
183}
184
186{
187 Q_Q(QQuickWidget);
188
190
191 if (!useSoftwareRenderer) {
194 else
195 qWarning("QQuickWidget is not supported on this platform.");
196 }
197
198 engine = e;
199
201 engine.data()->setIncubationController(offscreenWindow->incubationController());
202
203 q->setMouseTracking(true);
204 q->setFocusPolicy(Qt::StrongFocus);
205#ifndef Q_OS_MACOS
206 /*
207 Usually, a QTouchEvent comes from a touchscreen, and we want those
208 touch events in Qt Quick. But on macOS, there are no touchscreens, and
209 WA_AcceptTouchEvents has a different meaning: QApplication::notify()
210 calls the native-integration function registertouchwindow() to change
211 NSView::allowedTouchTypes to include NSTouchTypeMaskIndirect when the
212 trackpad cursor enters the window, and removes that mask when the
213 cursor exits. In other words, WA_AcceptTouchEvents enables getting
214 discrete touchpoints from the trackpad. We rather prefer to get mouse,
215 wheel and native gesture events from the trackpad (because those
216 provide more of a "native feel"). The only exception is for
217 MultiPointTouchArea, and it takes care of that for itself. So don't
218 automatically set WA_AcceptTouchEvents on macOS. The user can still do
219 it, but we don't recommend it.
220 */
221 q->setAttribute(Qt::WA_AcceptTouchEvents);
222#endif
223
224#if QT_CONFIG(quick_draganddrop)
225 q->setAcceptDrops(true);
226#endif
227
228 QObject::connect(renderControl, SIGNAL(renderRequested()), q, SLOT(triggerUpdate()));
229 QObject::connect(renderControl, SIGNAL(sceneChanged()), q, SLOT(triggerUpdate()));
230}
231
233{
234 Q_Q(const QQuickWidget);
235 if (!engine.isNull())
236 return;
237
238 engine = new QQmlEngine(const_cast<QQuickWidget*>(q));
239 engine.data()->setIncubationController(offscreenWindow->incubationController());
240}
241
243{
244 if (!useSoftwareRenderer && rhi) {
245 // For the user's own OpenGL code connected to some QQuickWindow signals.
247 }
248
250}
251
253{
254 Q_Q(QQuickWidget);
255
256 if (offscreenWindow->isPersistentSceneGraph()
257 && qGuiApp->testAttribute(Qt::AA_ShareOpenGLContexts)
259 {
260 return;
261 }
262
263 // In case of !isPersistentSceneGraph or when we need a new context due to
264 // the need to share resources with the new window's context, we must both
265 // invalidate the scenegraph and destroy the context. QQuickRenderControl
266 // must be recreated because its RHI will contain a dangling pointer to
267 // the context.
268
269 QScopedPointer<QQuickWindow> oldOffScreenWindow(offscreenWindow); // Do not delete before reparenting sgItem
270 offscreenWindow = nullptr;
271 delete renderControl;
272
275
276 QObject::connect(renderControl, SIGNAL(renderRequested()), q, SLOT(triggerUpdate()));
277 QObject::connect(renderControl, SIGNAL(sceneChanged()), q, SLOT(triggerUpdate()));
278
279 if (!source.isEmpty())
280 execute();
281 else if (QQuickItem *sgItem = qobject_cast<QQuickItem *>(root))
282 sgItem->setParentItem(offscreenWindow->contentItem());
283}
284
286 : root(nullptr)
288 , offscreenWindow(nullptr)
289 , renderControl(nullptr)
290 , rhi(nullptr)
291 , outputTexture(nullptr)
292 , depthStencil(nullptr)
293 , msaaBuffer(nullptr)
294 , rt(nullptr)
295 , rtRp(nullptr)
296 , resizeMode(QQuickWidget::SizeViewToRootObject)
297 , initialSize(0,0)
298 , eventPending(false)
299 , updatePending(false)
300 , fakeHidden(false)
301 , requestedSamples(0)
302 , useSoftwareRenderer(false)
303 , forceFullUpdate(false)
304 , deviceLost(false)
305{
306}
307
309{
310 Q_Q(QQuickWidget);
312 q->destroyFramebufferObject();
313 delete offscreenWindow;
314 delete renderControl;
316}
317
319{
320 Q_Q(QQuickWidget);
321 ensureEngine();
322
323 if (root) {
324 delete root;
325 root = nullptr;
326 }
327 if (component) {
328 delete component;
329 component = nullptr;
330 }
331 if (!source.isEmpty()) {
333 if (!component->isLoading()) {
334 q->continueExecute();
335 } else {
337 q, SLOT(continueExecute()));
338 }
339 }
340}
341
343 const QRectF &oldGeometry)
344{
345 Q_Q(QQuickWidget);
346 if (resizeItem == root && resizeMode == QQuickWidget::SizeViewToRootObject) {
347 // wait for both width and height to be changed
349 }
350 QQuickItemChangeListener::itemGeometryChanged(resizeItem, change, oldGeometry);
351}
352
353void QQuickWidgetPrivate::render(bool needsSync)
354{
355 Q_Q(QQuickWidget);
356 if (!useSoftwareRenderer) {
357 if (deviceLost) {
358 deviceLost = false;
360 q->createFramebufferObject();
361 }
362
363 if (!rhi) {
364 qWarning("QQuickWidget: Attempted to render scene with no rhi");
365 return;
366 }
367
368 // createFramebufferObject() bails out when the size is empty. In this case
369 // we cannot render either.
370 if (!outputTexture)
371 return;
372
376 // graphics resources controlled by us must be released
378 // skip this round and hope that the tlw's repaint manager will manage to reinitialize
379 deviceLost = true;
380 return;
381 }
383 qWarning("QQuickWidget: Failed to begin recording a frame");
384 return;
385 }
386
387 if (needsSync) {
390 }
391
393
395 } else {
396 //Software Renderer
397 if (needsSync) {
400 }
401 if (!offscreenWindow)
402 return;
404 auto softwareRenderer = static_cast<QSGSoftwareRenderer*>(cd->renderer);
405 if (softwareRenderer && !softwareImage.isNull()) {
406 softwareRenderer->setCurrentPaintDevice(&softwareImage);
407 if (forceFullUpdate) {
408 softwareRenderer->markDirty();
409 forceFullUpdate = false;
410 }
412
413 updateRegion += softwareRenderer->flushRegion();
414 }
415 }
416}
417
419{
420 Q_Q(QQuickWidget);
421 updatePending = false;
422
423 if (!q->isVisible() || fakeHidden)
424 return;
425
426 render(true);
427
428#if QT_CONFIG(graphicsview)
429 if (q->window()->graphicsProxyWidget())
430 QWidgetPrivate::nearestGraphicsProxyWidget(q)->update();
431 else
432#endif
433 {
435 q->update(); // schedule composition
436 else if (!updateRegion.isEmpty())
437 q->update(updateRegion);
438 }
439}
440
442{
443 if (!useSoftwareRenderer && !rhi)
444 return QImage();
445
446 // grabWindow() does not work for the rhi case, we are in control of the
447 // render target, and so it is up to us to read it back. When the software
448 // renderer is in use, just call grabWindow().
449
450 if (outputTexture) {
451 render(true);
452 QRhiCommandBuffer *cb = nullptr;
455 QRhiReadbackResult readResult;
456 resUpd->readBackTexture(QRhiReadbackDescription(outputTexture), &readResult);
457 cb->resourceUpdate(resUpd);
459 if (!readResult.data.isEmpty()) {
460 QImage wrapperImage(reinterpret_cast<const uchar *>(readResult.data.constData()),
461 readResult.pixelSize.width(), readResult.pixelSize.height(),
463 if (rhi->isYUpInFramebuffer())
464 return wrapperImage.mirrored();
465 else
466 return wrapperImage.copy();
467 }
468 return QImage();
469 }
470
471 return offscreenWindow->grabWindow();
472}
473
474// Intentionally not overriding the QQuickWindow's focusObject.
475// Key events should go to our key event handlers, and then to the
476// QQuickWindow, not any in-scene item.
477
636 : QWidget(*(new QQuickWidgetPrivate), parent, {})
637{
638 d_func()->init();
639}
640
648 : QQuickWidget(parent)
649{
651}
652
661 : QWidget(*(new QQuickWidgetPrivate), parent, {})
662{
663 d_func()->init(engine);
664}
665
670{
671 // Ensure that the component is destroyed before the engine; the engine may
672 // be a child of the QQuickWidgetPrivate, and will be destroyed by its dtor
673 Q_D(QQuickWidget);
674 delete d->root;
675 d->root = nullptr;
676
677 if (d->rhi)
678 d->rhi->removeCleanupCallback(this);
679
680 // NB! resetting graphics resources must be done from this destructor,
681 // *not* from the private class' destructor. This is due to how destruction
682 // works and due to the QWidget dtor (for toplevels) destroying the repaint
683 // manager and rhi before the (QObject) private gets destroyed. Hence must
684 // do it here early on.
685 d->destroy();
686}
687
709{
710 Q_D(QQuickWidget);
711 d->source = url;
712 d->execute();
713}
714
721{
722 Q_D(QQuickWidget);
723 d->source = url;
724 d->component = component;
725
726 if (d->component && d->component->isError()) {
727 const QList<QQmlError> errorList = d->component->errors();
728 for (const QQmlError &error : errorList) {
729 QMessageLogger(error.url().toString().toLatin1().constData(), error.line(), nullptr).warning()
730 << error;
731 }
733 return;
734 }
735
736 d->setRootObject(item);
738}
739
746{
747 Q_D(const QQuickWidget);
748 return d->source;
749}
750
756{
757 Q_D(const QQuickWidget);
758 d->ensureEngine();
759 return const_cast<QQmlEngine *>(d->engine.data());
760}
761
770{
771 Q_D(const QQuickWidget);
772 d->ensureEngine();
773 return d->engine.data()->rootContext();
774}
775
816{
817 Q_D(const QQuickWidget);
818 if (!d->engine && !d->source.isEmpty())
819 return QQuickWidget::Error;
820
821 if (!d->component)
822 return QQuickWidget::Null;
823
824 if (d->component->status() == QQmlComponent::Ready && !d->root)
825 return QQuickWidget::Error;
826
827 return QQuickWidget::Status(d->component->status());
828}
829
836QList<QQmlError> QQuickWidget::errors() const
837{
838 Q_D(const QQuickWidget);
839 QList<QQmlError> errs;
840
841 if (d->component)
842 errs = d->component->errors();
843
844 if (!d->engine && !d->source.isEmpty()) {
846 error.setDescription(QLatin1String("QQuickWidget: invalid qml engine."));
847 errs << error;
848 }
849 if (d->component && d->component->status() == QQmlComponent::Ready && !d->root) {
851 error.setDescription(QLatin1String("QQuickWidget: invalid root object."));
852 errs << error;
853 }
854
855 return errs;
856}
857
876{
877 Q_D(QQuickWidget);
878 if (d->resizeMode == mode)
879 return;
880
881 if (d->root) {
882 if (d->resizeMode == SizeViewToRootObject) {
884 p->removeItemChangeListener(d, QQuickItemPrivate::Geometry);
885 }
886 }
887
888 d->resizeMode = mode;
889 if (d->root) {
890 d->initResize();
891 }
892}
893
895{
896 if (root) {
899 p->addItemChangeListener(this, QQuickItemPrivate::Geometry);
900 }
901 }
902 updateSize();
903}
904
906{
907 Q_Q(QQuickWidget);
908 if (!root)
909 return;
910
912 QSize newSize = QSize(root->width(), root->height());
913 if (newSize.isValid()) {
914 if (newSize != q->size()) {
915 q->resize(newSize);
916 q->updateGeometry();
917 } else if (offscreenWindow->size().isEmpty()) {
918 // QQuickDeliveryAgentPrivate::deliverHoverEvent() ignores events that
919 // occur outside of QQuickRootItem's geometry, so we need it to match root's size.
921 }
922 }
924 const bool needToUpdateWidth = !qFuzzyCompare(q->width(), root->width());
925 const bool needToUpdateHeight = !qFuzzyCompare(q->height(), root->height());
926
927 if (needToUpdateWidth && needToUpdateHeight) {
928 // Make sure that we have realistic sizing behavior by following
929 // what on-screen windows would do and resize everything, not just
930 // the root item. We do this because other types may be relying on
931 // us to behave correctly.
932 const QSizeF newSize(q->width(), q->height());
933 offscreenWindow->resize(newSize.toSize());
935 root->setSize(newSize);
936 } else if (needToUpdateWidth) {
937 const int newWidth = q->width();
938 offscreenWindow->setWidth(newWidth);
940 root->setWidth(newWidth);
941 } else if (needToUpdateHeight) {
942 const int newHeight = q->height();
943 offscreenWindow->setHeight(newHeight);
945 root->setHeight(newHeight);
946 }
947 }
948}
949
956{
957 Q_Q(QQuickWidget);
958 if (offscreenWindow == nullptr)
959 return;
960
961 const QPoint &pos = q->mapToGlobal(QPoint(0, 0));
962 if (offscreenWindow->position() != pos)
963 offscreenWindow->setPosition(pos);
964}
965
967{
969 int widthCandidate = -1;
970 int heightCandidate = -1;
971 if (root) {
972 widthCandidate = root->width();
973 heightCandidate = root->height();
974 }
975 if (widthCandidate > 0) {
976 rootObjectSize.setWidth(widthCandidate);
977 }
978 if (heightCandidate > 0) {
979 rootObjectSize.setHeight(heightCandidate);
980 }
981 return rootObjectSize;
982}
983
985{
986 Q_Q(QQuickWidget);
987
988 QString translatedMessage;
989 QString untranslatedMessage;
990 QQuickWindowPrivate::rhiCreationFailureMessage(QLatin1String("QRhi"), &translatedMessage, &untranslatedMessage);
991
993 const bool signalConnected = q->isSignalConnected(errorSignal);
994 if (signalConnected)
995 emit q->sceneGraphError(QQuickWindow::ContextNotAvailable, translatedMessage);
996
997#if defined(Q_OS_WIN) && QT_CONFIG(messagebox)
998 if (!signalConnected && !QLibraryInfo::isDebugBuild() && !GetConsoleWindow())
1000#endif // Q_OS_WIN
1001 if (!signalConnected)
1002 qFatal("%s", qPrintable(untranslatedMessage));
1003}
1004
1022
1023// Never called by Software Rendering backend
1025{
1026 Q_Q(QQuickWidget);
1027
1028 // when reparenting, the rhi may suddenly be different
1029 if (rhi) {
1030 QRhi *backingStoreRhi = QWidgetPrivate::rhi();
1031 if (backingStoreRhi && rhi != backingStoreRhi)
1032 rhi = nullptr;
1033 }
1034
1035 // On hide-show we may invalidate() (when !isPersistentSceneGraph) but our
1036 // context is kept. We may need to initialize() again, though.
1037 const bool onlyNeedsSgInit = rhi && !offscreenWindow->isSceneGraphInitialized();
1038
1039 if (!onlyNeedsSgInit) {
1040 if (rhi)
1041 return;
1042
1043 if (QRhi *backingStoreRhi = QWidgetPrivate::rhi()) {
1044 rhi = backingStoreRhi;
1045 // We don't own the RHI, so make sure we clean up if it goes away
1046 rhi->addCleanupCallback(q, [this](QRhi *rhi) {
1047 if (this->rhi == rhi) {
1049 deviceLost = true;
1050 this->rhi = nullptr;
1051 }
1052 });
1053 }
1054
1055 if (!rhi) {
1056 // The widget (and its parent chain, if any) may not be shown at
1057 // all, yet one may still want to use it for grabs. This is
1058 // ridiculous of course because the rendering infrastructure is
1059 // tied to the top-level widget that initializes upon expose, but
1060 // it has to be supported.
1062 offscreenRenderer.setFormat(q->format());
1063 // no window passed in, so no swapchain, but we get a functional QRhi which we own
1066 }
1067
1068 // Could be that something else already initialized the window with some
1069 // other graphics API for the QRhi, that's not good.
1070 if (rhi && rhi->backend() != QBackingStoreRhiSupport::apiToRhiBackend(graphicsApiToBackingStoreRhiApi(QQuickWindow::graphicsApi()))) {
1071 qWarning("The top-level window is not using the expected graphics API for composition, "
1072 "'%s' is not compatible with this QQuickWidget",
1073 rhi->backendName());
1074 rhi = nullptr;
1075 }
1076 }
1077
1078 if (rhi) {
1079 if (!offscreenWindow->isSceneGraphInitialized()) {
1081#if QT_CONFIG(vulkan)
1082 if (QWindow *w = q->window()->windowHandle())
1083 offscreenWindow->setVulkanInstance(w->vulkanInstance());
1084 else if (rhi == offscreenRenderer.rhi())
1085 offscreenWindow->setVulkanInstance(QVulkanDefaultInstance::instance());
1086#endif
1088 }
1089 } else {
1090 qWarning("QQuickWidget: Failed to get a QRhi from the top-level widget's window");
1091 }
1092}
1093
1094void QQuickWidget::createFramebufferObject()
1095{
1096 Q_D(QQuickWidget);
1097
1098 // Could come from Show -> initializeWithRhi -> sceneGraphInitialized in which case the size may
1099 // still be invalid on some platforms. Bail out. A resize will come later on.
1100 if (size().isEmpty())
1101 return;
1102
1103 // Even though this is just an offscreen window we should set the position on it, as it might be
1104 // useful for an item to know the actual position of the scene.
1105 // Note: The position will be update when we get a move event (see: updatePosition()).
1106 const QPoint &globalPos = mapToGlobal(QPoint(0, 0));
1107 d->offscreenWindow->setGeometry(globalPos.x(), globalPos.y(), width(), height());
1108
1109 if (d->useSoftwareRenderer) {
1110 const QSize imageSize = size() * devicePixelRatio();
1112 d->softwareImage.setDevicePixelRatio(devicePixelRatio());
1113 d->forceFullUpdate = true;
1114 return;
1115 }
1116
1117 if (!d->rhi) {
1118 qWarning("QQuickWidget: Attempted to create output texture with no QRhi");
1119 return;
1120 }
1121
1122 int samples = d->requestedSamples;
1123 if (d->rhi->isFeatureSupported(QRhi::MultisampleRenderBuffer))
1125 else
1126 samples = 0;
1127
1128 const QSize fboSize = size() * devicePixelRatio();
1129
1130 // Could be a simple hide - show, in which case the previous texture is just fine.
1131 if (!d->outputTexture) {
1132 d->outputTexture = d->rhi->newTexture(QRhiTexture::RGBA8, fboSize, 1, QRhiTexture::RenderTarget | QRhiTexture::UsedAsTransferSource);
1133 if (!d->outputTexture->create()) {
1134 qWarning("QQuickWidget: failed to create output texture of size %dx%d",
1135 fboSize.width(), fboSize.height());
1136 }
1137 }
1138 if (!d->depthStencil) {
1139 d->depthStencil = d->rhi->newRenderBuffer(QRhiRenderBuffer::DepthStencil, fboSize, samples);
1140 if (!d->depthStencil->create()) {
1141 qWarning("QQuickWidget: failed to create depth/stencil buffer of size %dx%d and sample count %d",
1142 fboSize.width(), fboSize.height(), samples);
1143 }
1144 }
1145 if (samples > 1 && !d->msaaBuffer) {
1146 d->msaaBuffer = d->rhi->newRenderBuffer(QRhiRenderBuffer::Color, fboSize, samples);
1147 if (!d->msaaBuffer->create()) {
1148 qWarning("QQuickWidget: failed to create multisample renderbuffer of size %dx%d and sample count %d",
1149 fboSize.width(), fboSize.height(), samples);
1150 }
1151 }
1152 if (!d->rt) {
1154 QRhiColorAttachment colorAtt;
1155 if (samples <= 1) {
1156 colorAtt.setTexture(d->outputTexture);
1157 } else {
1158 colorAtt.setRenderBuffer(d->msaaBuffer);
1159 colorAtt.setResolveTexture(d->outputTexture);
1160 }
1161 rtDesc.setColorAttachments({ colorAtt });
1162 rtDesc.setDepthStencilBuffer(d->depthStencil);
1163 d->rt = d->rhi->newTextureRenderTarget(rtDesc);
1164 d->rtRp = d->rt->newCompatibleRenderPassDescriptor();
1165 d->rt->setRenderPassDescriptor(d->rtRp);
1166 d->rt->create();
1167 }
1168 if (d->outputTexture->pixelSize() != fboSize) {
1169 d->outputTexture->setPixelSize(fboSize);
1170 if (!d->outputTexture->create()) {
1171 qWarning("QQuickWidget: failed to create resized output texture of size %dx%d",
1172 fboSize.width(), fboSize.height());
1173 }
1174 d->depthStencil->setPixelSize(fboSize);
1175 if (!d->depthStencil->create()) {
1176 qWarning("QQuickWidget: failed to create resized depth/stencil buffer of size %dx%d",
1177 fboSize.width(), fboSize.height());
1178 }
1179 if (d->msaaBuffer) {
1180 d->msaaBuffer->setPixelSize(fboSize);
1181 if (!d->msaaBuffer->create()) {
1182 qWarning("QQuickWidget: failed to create resized multisample renderbuffer of size %dx%d",
1183 fboSize.width(), fboSize.height());
1184 }
1185 }
1186 }
1187
1188 d->offscreenWindow->setRenderTarget(QQuickRenderTarget::fromRhiRenderTarget(d->rt));
1189
1190 d->renderControl->setSamples(samples);
1191
1192 // Sanity check: The window must not have an underlying platform window.
1193 // Having one would mean create() was called and platforms that only support
1194 // a single native window were in trouble.
1195 Q_ASSERT(!d->offscreenWindow->handle());
1196}
1197
1198void QQuickWidget::destroyFramebufferObject()
1199{
1200 Q_D(QQuickWidget);
1201
1202 if (d->useSoftwareRenderer) {
1203 d->softwareImage = QImage();
1204 return;
1205 }
1206
1207 delete d->rt;
1208 d->rt = nullptr;
1209 delete d->rtRp;
1210 d->rtRp = nullptr;
1211 delete d->depthStencil;
1212 d->depthStencil = nullptr;
1213 delete d->msaaBuffer;
1214 d->msaaBuffer = nullptr;
1215 delete d->outputTexture;
1216 d->outputTexture = nullptr;
1217}
1218
1220{
1221 Q_D(const QQuickWidget);
1222 return d->resizeMode;
1223}
1224
1228void QQuickWidget::continueExecute()
1229{
1230 Q_D(QQuickWidget);
1231 disconnect(d->component, SIGNAL(statusChanged(QQmlComponent::Status)), this, SLOT(continueExecute()));
1232
1233 if (d->component->isError()) {
1234 const QList<QQmlError> errorList = d->component->errors();
1235 for (const QQmlError &error : errorList) {
1236 QMessageLogger(error.url().toString().toLatin1().constData(), error.line(), nullptr).warning()
1237 << error;
1238 }
1240 return;
1241 }
1242
1243 QObject *obj = d->component->create();
1244
1245 if (d->component->isError()) {
1246 const QList<QQmlError> errorList = d->component->errors();
1247 for (const QQmlError &error : errorList) {
1248 QMessageLogger(error.url().toString().toLatin1().constData(), error.line(), nullptr).warning()
1249 << error;
1250 }
1252 return;
1253 }
1254
1255 d->setRootObject(obj);
1257}
1258
1259
1264{
1265 Q_Q(QQuickWidget);
1266 if (root == obj)
1267 return;
1268 if (QQuickItem *sgItem = qobject_cast<QQuickItem *>(obj)) {
1269 root = sgItem;
1271 } else if (qobject_cast<QWindow *>(obj)) {
1272 qWarning() << "QQuickWidget does not support using windows as a root item." << Qt::endl
1273 << Qt::endl
1274 << "If you wish to create your root window from QML, consider using QQmlApplicationEngine instead." << Qt::endl;
1275 } else {
1276 qWarning() << "QQuickWidget only supports loading of root objects that derive from QQuickItem." << Qt::endl
1277 << Qt::endl
1278 << "Ensure your QML code is written for QtQuick 2, and uses a root that is or" << Qt::endl
1279 << "inherits from QtQuick's Item (not a Timer, QtObject, etc)." << Qt::endl;
1280 delete obj;
1281 root = nullptr;
1282 }
1283 if (root) {
1285 bool resized = q->testAttribute(Qt::WA_Resized);
1286 if ((resizeMode == QQuickWidget::SizeViewToRootObject || !resized) &&
1287 initialSize != q->size()) {
1288 q->resize(initialSize);
1289 }
1290 initResize();
1291 }
1292}
1293
1295{
1296 const_cast<QQuickWidgetPrivate *>(this)->ensureBackingScene();
1298 return {};
1299
1301
1303 // This is only here to support some of the env.vars. (such as
1304 // QSG_RHI_DEBUG_LAYER). There is currently no way to set a
1305 // QQuickGraphicsConfiguration for a QQuickWidget, which means things like
1306 // the pipeline cache are just not available. That is something to support
1307 // on the widget/backingstore level since that's where the QRhi is
1308 // controlled in this case.
1309 const bool debugLayerRequested = wd->graphicsConfig.isDebugLayerEnabled();
1310 config.setDebugLayer(debugLayerRequested);
1311 return config;
1312}
1313
1315{
1316 Q_Q(const QQuickWidget);
1317 if (!q->isWindow() && q->internalWinId()) {
1318 qWarning() << "QQuickWidget cannot be used as a native child widget."
1319 << "Consider setting Qt::AA_DontCreateNativeWidgetSiblings";
1320 return {};
1321 }
1322 return { outputTexture, nullptr };
1323}
1324
1325QPlatformTextureList::Flags QQuickWidgetPrivate::textureListFlags()
1326{
1327 QPlatformTextureList::Flags flags = QWidgetPrivate::textureListFlags();
1329 return flags;
1330}
1331
1337{
1338 Q_D(QQuickWidget);
1339 if (!e || e->timerId() == d->resizetimer.timerId()) {
1340 d->updateSize();
1341 d->resizetimer.stop();
1342 } else if (e->timerId() == d->updateTimer.timerId()) {
1343 d->eventPending = false;
1344 d->updateTimer.stop();
1345 if (d->updatePending)
1346 d->renderSceneGraph();
1347 }
1348}
1349
1355{
1356 Q_D(const QQuickWidget);
1357 QSize rootObjectSize = d->rootObjectSize();
1358 if (rootObjectSize.isEmpty()) {
1359 return size();
1360 } else {
1361 return rootObjectSize;
1362 }
1363}
1364
1373{
1374 Q_D(const QQuickWidget);
1375 return d->initialSize;
1376}
1377
1384{
1385 Q_D(const QQuickWidget);
1386 return d->root;
1387}
1388
1395{
1396 Q_D(QQuickWidget);
1397 if (d->resizeMode == SizeRootObjectToView)
1398 d->updateSize();
1399
1400 if (e->size().isEmpty()) {
1401 //stop rendering
1402 d->fakeHidden = true;
1403 return;
1404 }
1405
1406 bool needsSync = false;
1407 if (d->fakeHidden) {
1408 //restart rendering
1409 d->fakeHidden = false;
1410 needsSync = true;
1411 }
1412
1413 // Software Renderer
1414 if (d->useSoftwareRenderer) {
1415 needsSync = true;
1416 if (d->softwareImage.size() != size() * devicePixelRatio()) {
1417 createFramebufferObject();
1418 }
1419 } else {
1420 if (d->rhi) {
1421 // Bail out when receiving a resize after scenegraph invalidation. This can happen
1422 // during hide - resize - show sequences and also during application exit.
1423 if (!d->outputTexture && !d->offscreenWindow->isSceneGraphInitialized())
1424 return;
1425 if (!d->outputTexture || d->outputTexture->pixelSize() != size() * devicePixelRatio()) {
1426 needsSync = true;
1427 createFramebufferObject();
1428 }
1429 } else {
1430 // This will result in a scenegraphInitialized() signal which
1431 // is connected to createFramebufferObject().
1432 needsSync = true;
1433 d->initializeWithRhi();
1434 }
1435
1436 if (!d->rhi) {
1437 qWarning("QQuickWidget::resizeEvent() no QRhi");
1438 return;
1439 }
1440 }
1441
1442 d->render(needsSync);
1443}
1444
1447{
1448 Q_D(QQuickWidget);
1450 Q_QUICK_INPUT_PROFILE(QQuickProfiler::Key, QQuickProfiler::InputKeyPress, event.key(),
1452 QCoreApplication::sendEvent(d->offscreenWindow, &event);
1453
1455 Q_QUICK_INPUT_PROFILE(QQuickProfiler::Key, QQuickProfiler::InputKeyRelease, releaseEvent.key(),
1457 QCoreApplication::sendEvent(d->offscreenWindow, &releaseEvent);
1458 return event.isAccepted();
1459}
1460
1463{
1464 Q_D(QQuickWidget);
1465 Q_QUICK_INPUT_PROFILE(QQuickProfiler::Key, QQuickProfiler::InputKeyPress, e->key(),
1466 e->modifiers());
1467
1468 QCoreApplication::sendEvent(d->offscreenWindow, e);
1469}
1470
1473{
1474 Q_D(QQuickWidget);
1475 Q_QUICK_INPUT_PROFILE(QQuickProfiler::Key, QQuickProfiler::InputKeyRelease, e->key(),
1476 e->modifiers());
1477
1478 QCoreApplication::sendEvent(d->offscreenWindow, e);
1479}
1480
1483{
1484 Q_D(QQuickWidget);
1485 Q_QUICK_INPUT_PROFILE(QQuickProfiler::Mouse, QQuickProfiler::InputMouseMove, e->position().x(),
1486 e->position().y());
1487
1488 // Put position into the event's position and scenePosition, and globalPosition into the
1489 // event's globalPosition. This way the scenePosition in e is ignored and is replaced by
1490 // position. This is necessary because QQuickWindow thinks of itself as a
1491 // top-level window always.
1492 QMouseEvent mappedEvent(e->type(), e->position(), e->position(), e->globalPosition(),
1493 e->button(), e->buttons(), e->modifiers(), e->source());
1494 // It's not just the timestamp but also the globalPressPosition, velocity etc.
1495 mappedEvent.setTimestamp(e->timestamp());
1496 QCoreApplication::sendEvent(d->offscreenWindow, &mappedEvent);
1497 e->setAccepted(mappedEvent.isAccepted());
1498}
1499
1502{
1503 Q_D(QQuickWidget);
1504 Q_QUICK_INPUT_PROFILE(QQuickProfiler::Mouse, QQuickProfiler::InputMouseDoubleClick,
1505 e->button(), e->buttons());
1506
1507 // As the second mouse press is suppressed in widget windows we emulate it here for QML.
1508 // See QTBUG-25831
1510 e->button(), e->buttons(), e->modifiers(), e->source());
1511 pressEvent.setTimestamp(e->timestamp());
1512 QCoreApplication::sendEvent(d->offscreenWindow, &pressEvent);
1513 e->setAccepted(pressEvent.isAccepted());
1514 QMouseEvent mappedEvent(e->type(), e->position(), e->position(), e->globalPosition(),
1515 e->button(), e->buttons(), e->modifiers(), e->source());
1516 mappedEvent.setTimestamp(e->timestamp());
1517 QCoreApplication::sendEvent(d->offscreenWindow, &mappedEvent);
1518}
1519
1522{
1523 Q_D(QQuickWidget);
1524 bool shouldTriggerUpdate = true;
1525
1526 if (!d->useSoftwareRenderer) {
1527 d->initializeWithRhi();
1528
1529 if (d->offscreenWindow->isSceneGraphInitialized()) {
1530 shouldTriggerUpdate = false;
1531 d->render(true);
1532 // render() may have led to a QQuickWindow::update() call (for
1533 // example, having a scene with a QQuickFramebufferObject::Renderer
1534 // calling update() in its render()) which in turn results in
1535 // renderRequested in the rendercontrol, ending up in
1536 // triggerUpdate. In this case just calling update() is not
1537 // acceptable, we need the full renderSceneGraph issued from
1538 // timerEvent().
1539 if (!d->eventPending && d->updatePending) {
1540 d->updatePending = false;
1541 update();
1542 }
1543 }
1544 }
1545
1546 if (shouldTriggerUpdate)
1547 triggerUpdate();
1548
1549 // note offscreenWindow is "QQuickWidgetOffscreenWindow" instance
1550 d->offscreenWindow->setVisible(true);
1551 if (QQmlInspectorService *service = QQmlDebugConnector::service<QQmlInspectorService>())
1552 service->setParentWindow(d->offscreenWindow, window()->windowHandle());
1553}
1554
1557{
1558 Q_D(QQuickWidget);
1559 if (!d->offscreenWindow->isPersistentSceneGraph())
1560 d->invalidateRenderControl();
1561 // note offscreenWindow is "QQuickWidgetOffscreenWindow" instance
1562 d->offscreenWindow->setVisible(false);
1563 if (QQmlInspectorService *service = QQmlDebugConnector::service<QQmlInspectorService>())
1564 service->setParentWindow(d->offscreenWindow, d->offscreenWindow);
1565}
1566
1569{
1570 Q_D(QQuickWidget);
1571 Q_QUICK_INPUT_PROFILE(QQuickProfiler::Mouse, QQuickProfiler::InputMousePress, e->button(),
1572 e->buttons());
1573
1574 QMouseEvent mappedEvent(e->type(), e->position(), e->position(), e->globalPosition(),
1575 e->button(), e->buttons(), e->modifiers(), e->source());
1576 mappedEvent.setTimestamp(e->timestamp());
1577 QCoreApplication::sendEvent(d->offscreenWindow, &mappedEvent);
1578 e->setAccepted(mappedEvent.isAccepted());
1579}
1580
1583{
1584 Q_D(QQuickWidget);
1585 Q_QUICK_INPUT_PROFILE(QQuickProfiler::Mouse, QQuickProfiler::InputMouseRelease, e->button(),
1586 e->buttons());
1587
1588 QMouseEvent mappedEvent(e->type(), e->position(), e->position(), e->globalPosition(),
1589 e->button(), e->buttons(), e->modifiers(), e->source());
1590 mappedEvent.setTimestamp(e->timestamp());
1591 QCoreApplication::sendEvent(d->offscreenWindow, &mappedEvent);
1592 e->setAccepted(mappedEvent.isAccepted());
1593}
1594
1595#if QT_CONFIG(wheelevent)
1597void QQuickWidget::wheelEvent(QWheelEvent *e)
1598{
1599 Q_D(QQuickWidget);
1600 Q_QUICK_INPUT_PROFILE(QQuickProfiler::Mouse, QQuickProfiler::InputMouseWheel,
1601 e->angleDelta().x(), e->angleDelta().y());
1602
1603 // Wheel events only have local and global positions, no need to map.
1604 QCoreApplication::sendEvent(d->offscreenWindow, e);
1605}
1606#endif
1607
1612{
1613 Q_D(QQuickWidget);
1614 d->offscreenWindow->focusInEvent(event);
1615}
1616
1621{
1622 Q_D(QQuickWidget);
1623 d->offscreenWindow->focusOutEvent(event);
1624}
1625
1627{
1628 // No more than one of these 3 can be set
1630 return Qt::WindowMinimized;
1632 return Qt::WindowMaximized;
1634 return Qt::WindowFullScreen;
1635
1636 // No state means "windowed" - we ignore Qt::WindowActive
1637 return Qt::WindowNoState;
1638}
1639
1641{
1642 auto item = qobject_cast<QQuickItem *>(object);
1643 if (!item)
1644 return;
1645
1646 // Remap all QRectF values.
1648 if (e->queries() & query) {
1649 auto value = e->value(query);
1650 if (value.canConvert<QRectF>())
1651 e->setValue(query, item->mapRectToScene(value.toRectF()));
1652 }
1653 }
1654 // Remap all QPointF values.
1655 if (e->queries() & Qt::ImCursorPosition) {
1656 auto value = e->value(Qt::ImCursorPosition);
1657 if (value.canConvert<QPointF>())
1659 }
1660}
1661
1664{
1665 Q_D(QQuickWidget);
1666
1667 switch (e->type()) {
1668
1669 case QEvent::Leave:
1670 case QEvent::TouchBegin:
1671 case QEvent::TouchEnd:
1673 case QEvent::TouchCancel: {
1674 // Touch events only have local and global positions, no need to map.
1675 bool res = QCoreApplication::sendEvent(d->offscreenWindow, e);
1676 if (e->isAccepted() && e->type() == QEvent::TouchBegin) {
1677 // If the TouchBegin got accepted, then make sure all points that have
1678 // an exclusive grabber are also accepted so that the widget code for
1679 // delivering touch events make this widget an implicit grabber of those
1680 // points.
1681 QPointerEvent *pointerEvent = static_cast<QPointerEvent *>(e);
1682 auto deliveredPoints = pointerEvent->points();
1683 for (auto &point : deliveredPoints) {
1684 if (pointerEvent->exclusiveGrabber(point) || !pointerEvent->passiveGrabbers(point).isEmpty())
1685 point.setAccepted(true);
1686 }
1687 }
1688 return res;
1689 }
1690
1692 return QCoreApplication::sendEvent(d->offscreenWindow, e);
1693
1695 return QCoreApplication::sendEvent(d->offscreenWindow->focusObject(), e);
1697 {
1698 bool eventResult = QCoreApplication::sendEvent(d->offscreenWindow->focusObject(), e);
1699 // The result in focusObject are based on offscreenWindow. But
1700 // the inputMethodTransform won't get updated because the focus
1701 // is on QQuickWidget. We need to remap the value based on the
1702 // widget.
1703 remapInputMethodQueryEvent(d->offscreenWindow->focusObject(), static_cast<QInputMethodQueryEvent *>(e));
1704 return eventResult;
1705 }
1706
1708 if (d->rhi)
1709 d->rhi->removeCleanupCallback(this);
1710 d->invalidateRenderControl();
1711 d->deviceLost = true;
1712 d->rhi = nullptr;
1713 break;
1714
1716 d->handleWindowChange();
1717 break;
1718
1720 {
1721 QScreen *newScreen = screen();
1722 if (d->offscreenWindow)
1723 d->offscreenWindow->setScreen(newScreen);
1724 break;
1725 }
1727 if (d->useSoftwareRenderer || d->outputTexture) {
1728 // This will check the size taking the devicePixelRatio into account
1729 // and recreate if needed.
1730 createFramebufferObject();
1731 d->render(true);
1732 }
1733 if (d->offscreenWindow) {
1734 QEvent dprChangeEvent(QEvent::DevicePixelRatioChange);
1735 QGuiApplication::sendEvent(d->offscreenWindow, &dprChangeEvent);
1736 }
1737 break;
1738 case QEvent::Show:
1739 case QEvent::Move:
1740 d->updatePosition();
1741 break;
1742
1744 d->offscreenWindow->setWindowState(resolveWindowState(windowState()));
1745 break;
1746
1748 return QCoreApplication::sendEvent(d->offscreenWindow, e);
1749
1750 case QEvent::Enter: {
1751 QEnterEvent *enterEvent = static_cast<QEnterEvent *>(e);
1752 QEnterEvent mappedEvent(enterEvent->position(), enterEvent->scenePosition(),
1753 enterEvent->globalPosition());
1754 const bool ret = QCoreApplication::sendEvent(d->offscreenWindow, &mappedEvent);
1755 e->setAccepted(mappedEvent.isAccepted());
1756 return ret;
1757 }
1758 default:
1759 break;
1760 }
1761
1762 return QWidget::event(e);
1763}
1764
1765#if QT_CONFIG(quick_draganddrop)
1766
1768void QQuickWidget::dragEnterEvent(QDragEnterEvent *e)
1769{
1770 Q_D(QQuickWidget);
1771 // Don't reject drag events for the entire widget when one
1772 // item rejects the drag enter
1773 d->offscreenWindow->event(e);
1774 e->accept();
1775}
1776
1778void QQuickWidget::dragMoveEvent(QDragMoveEvent *e)
1779{
1780 Q_D(QQuickWidget);
1781 // Drag/drop events only have local pos, so no need to map,
1782 // but QQuickWindow::event() does not return true
1783 d->offscreenWindow->event(e);
1784}
1785
1787void QQuickWidget::dragLeaveEvent(QDragLeaveEvent *e)
1788{
1789 Q_D(QQuickWidget);
1790 d->offscreenWindow->event(e);
1791}
1792
1794void QQuickWidget::dropEvent(QDropEvent *e)
1795{
1796 Q_D(QQuickWidget);
1797 d->offscreenWindow->event(e);
1798}
1799
1800#endif // quick_draganddrop
1801
1802// TODO: try to separate the two cases of
1803// 1. render() unconditionally without sync
1804// 2. sync() and then render if necessary
1805void QQuickWidget::triggerUpdate()
1806{
1807 Q_D(QQuickWidget);
1808 d->updatePending = true;
1809 if (!d->eventPending) {
1810 // There's no sense in immediately kicking a render off now, as
1811 // there may be a number of triggerUpdate calls to come from a multitude
1812 // of different sources (network, touch/mouse/keyboard, timers,
1813 // animations, ...), and we want to batch them all into single frames as
1814 // much as possible for the sake of interactivity and responsiveness.
1815 //
1816 // To achieve this, we set a timer and only perform the rendering when
1817 // this is complete.
1818 const int exhaustDelay = 5;
1819 d->updateTimer.start(exhaustDelay, Qt::PreciseTimer, this);
1820 d->eventPending = true;
1821 }
1822}
1823
1836{
1837 Q_D(QQuickWidget);
1838 QSurfaceFormat currentFormat = d->offscreenWindow->format();
1839 QSurfaceFormat newFormat = format;
1840 newFormat.setDepthBufferSize(qMax(newFormat.depthBufferSize(), currentFormat.depthBufferSize()));
1841 newFormat.setStencilBufferSize(qMax(newFormat.stencilBufferSize(), currentFormat.stencilBufferSize()));
1842 newFormat.setAlphaBufferSize(qMax(newFormat.alphaBufferSize(), currentFormat.alphaBufferSize()));
1843
1844 // Do not include the sample count. Requesting a multisampled context is not necessary
1845 // since we render into an FBO, never to an actual surface. What's more, attempting to
1846 // create a pbuffer with a multisampled config crashes certain implementations. Just
1847 // avoid the entire hassle, the result is the same.
1848 d->requestedSamples = newFormat.samples();
1849 newFormat.setSamples(0);
1850
1851 d->offscreenWindow->setFormat(newFormat);
1852}
1853
1862{
1863 Q_D(const QQuickWidget);
1864 return d->offscreenWindow->format();
1865}
1866
1873{
1874 return const_cast<QQuickWidgetPrivate *>(d_func())->grabFramebuffer();
1875}
1876
1888{
1889 Q_D(QQuickWidget);
1890 d->offscreenWindow->setColor(color);
1891}
1892
1912{
1913 Q_D(const QQuickWidget);
1914 return d->offscreenWindow;
1915}
1916
1921{
1922 Q_D(QQuickWidget);
1923 if (d->useSoftwareRenderer) {
1924 QPainter painter(this);
1925 d->updateRegion = d->updateRegion.united(event->region());
1926 if (d->updateRegion.isNull()) {
1927 //Paint everything
1928 painter.drawImage(rect(), d->softwareImage);
1929 } else {
1932 //Paint only the updated areas
1933 QRegion targetRegion;
1934 d->updateRegion.swap(targetRegion);
1935 for (auto targetRect : targetRegion) {
1936 auto sourceRect = transform.mapRect(QRectF(targetRect));
1937 painter.drawImage(targetRect, d->softwareImage, sourceRect);
1938 }
1939 }
1940 }
1941}
1942
1943void QQuickWidget::propagateFocusObjectChanged(QObject *focusObject)
1944{
1945 Q_D(QQuickWidget);
1946 if (QApplication::focusObject() != this)
1947 return;
1949 emit window->focusObjectChanged(focusObject);
1950}
1951
1953
1954#include "moc_qquickwidget_p.cpp"
1955
1956#include "moc_qquickwidget.cpp"
void setConfig(const QPlatformBackingStoreRhiConfig &config)
void setFormat(const QSurfaceFormat &format)
static QRhi::Implementation apiToRhiBackend(QPlatformBackingStoreRhiConfig::Api api)
void start(int msec, QObject *obj)
\obsolete Use chrono overload instead.
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition qcolor.h:31
static bool sendEvent(QObject *receiver, QEvent *event)
Sends event event directly to receiver receiver, using the notify() function.
QString applicationName
the name of this application
\inmodule QtGui
Definition qevent.h:165
\inmodule QtCore
Definition qcoreevent.h:45
virtual void setAccepted(bool accepted)
Definition qcoreevent.h:307
@ WindowStateChange
Definition qcoreevent.h:143
@ DevicePixelRatioChange
Definition qcoreevent.h:287
@ FocusAboutToChange
Definition qcoreevent.h:68
@ ScreenChangeInternal
Definition qcoreevent.h:276
@ WindowAboutToChangeInternal
Definition qcoreevent.h:285
@ ShortcutOverride
Definition qcoreevent.h:158
@ InputMethod
Definition qcoreevent.h:120
@ InputMethodQuery
Definition qcoreevent.h:261
@ KeyRelease
Definition qcoreevent.h:65
@ KeyPress
Definition qcoreevent.h:64
@ TouchCancel
Definition qcoreevent.h:264
@ MouseButtonPress
Definition qcoreevent.h:60
@ TouchUpdate
Definition qcoreevent.h:242
@ TouchBegin
Definition qcoreevent.h:241
@ WindowChangeInternal
Definition qcoreevent.h:275
Type type() const
Returns the event type.
Definition qcoreevent.h:304
bool isAccepted() const
Definition qcoreevent.h:308
The QFocusEvent class contains event parameters for widget focus events.
Definition qevent.h:470
QPointF mapToScene(const QPointF &point) const
Maps the point point, which is in this item's coordinate system, to the scene's coordinate system,...
QRectF mapRectToScene(const QRectF &rect) const
QList< QGraphicsView * > views() const
Returns a list of all the views that display this scene.
static QPlatformIntegration * platformIntegration()
static QObject * focusObject()
Returns the QObject in currently active window that will be final receiver of events tied to focus,...
The QHideEvent class provides an event which is sent after a widget is hidden.
Definition qevent.h:586
\inmodule QtGui
Definition qimage.h:37
bool isNull() const
Returns true if it is a null image, otherwise returns false.
Definition qimage.cpp:1222
@ Format_RGBA8888_Premultiplied
Definition qimage.h:60
@ Format_ARGB32_Premultiplied
Definition qimage.h:48
quint64 timestamp() const
Returns the window system's timestamp for this event.
Definition qevent.h:58
Qt::KeyboardModifiers modifiers() const
Returns the keyboard modifier flags that existed immediately before the event occurred.
Definition qevent.h:56
The QInputMethodQueryEvent class provides an event sent by the input context to input objects.
Definition qevent.h:679
QVariant value(Qt::InputMethodQuery query) const
Returns value of the property query.
Definition qevent.cpp:2381
void setValue(Qt::InputMethodQuery query, const QVariant &value)
Sets property query to value.
Definition qevent.cpp:2366
Qt::InputMethodQueries queries() const
Returns the properties queried by the event.
Definition qevent.h:684
The QKeyEvent class describes a key event.
Definition qevent.h:424
Qt::KeyboardModifiers modifiers() const
Returns the keyboard modifier flags that existed immediately after the event occurred.
Definition qevent.cpp:1468
int key() const
Returns the code of the key that was pressed or released.
Definition qevent.h:434
static bool isDebugBuild() noexcept Q_DECL_CONST_FUNCTION
bool isEmpty() const noexcept
Definition qlist.h:401
T & first()
Definition qlist.h:645
static StandardButton critical(QWidget *parent, const QString &title, const QString &text, StandardButtons buttons=Ok, StandardButton defaultButton=NoButton)
\inmodule QtCore
Definition qlogging.h:72
void void Q_DECL_COLD_FUNCTION void warning(const char *msg,...) const Q_ATTRIBUTE_FORMAT_PRINTF(2
Logs a warning message specified with format msg.
Definition qlogging.cpp:625
\inmodule QtCore
Definition qmetaobject.h:19
static QMetaMethod fromSignal(PointerToMemberFunction signal)
\inmodule QtGui
Definition qevent.h:196
Qt::MouseEventSource source() const
Definition qevent.cpp:801
\inmodule QtCore
Definition qobject.h:103
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
Q_WEAK_OVERLOAD void setObjectName(const QString &name)
Sets the object's name to name.
Definition qobject.h:127
qreal devicePixelRatio() const
The QPaintEvent class contains event parameters for paint events.
Definition qevent.h:486
The QPainter class performs low-level painting on widgets and other paint devices.
Definition qpainter.h:46
void drawImage(const QRectF &targetRect, const QImage &image, const QRectF &sourceRect, Qt::ImageConversionFlags flags=Qt::AutoColor)
Draws the rectangular portion source of the given image into the target rectangle in the paint device...
\inmodule QtCore\reentrant
Definition qpoint.h:217
constexpr qreal x() const noexcept
Returns the x coordinate of this point.
Definition qpoint.h:343
constexpr qreal y() const noexcept
Returns the y coordinate of this point.
Definition qpoint.h:348
\inmodule QtCore\reentrant
Definition qpoint.h:25
constexpr int x() const noexcept
Returns the x coordinate of this point.
Definition qpoint.h:130
constexpr int y() const noexcept
Returns the y coordinate of this point.
Definition qpoint.h:135
A base class for pointer events.
Definition qevent.h:73
QObject * exclusiveGrabber(const QEventPoint &point) const
Returns the object which has been set to receive all future update events and the release event conta...
Definition qevent.cpp:351
QList< QPointer< QObject > > passiveGrabbers(const QEventPoint &point) const
Returns the list of objects that have been requested to receive all future update events and the rele...
Definition qevent.cpp:384
virtual void setAccepted(bool accepted) override
\reimp
Definition qevent.cpp:318
const QList< QEventPoint > & points() const
Returns a list of points in this pointer event.
Definition qevent.h:87
T * data() const noexcept
Definition qpointer.h:73
bool isNull() const noexcept
Definition qpointer.h:84
The QQmlComponent class encapsulates a QML component definition.
Status
\qmltype Component \instantiates QQmlComponent\inqmlmodule QtQml
bool isLoading() const
Returns true if status() == QQmlComponent::Loading.
The QQmlContext class defines a context within a QML engine.
Definition qqmlcontext.h:25
The QQmlEngine class provides an environment for instantiating QML components.
Definition qqmlengine.h:57
QQmlIncubationController * incubationController() const
Returns the currently set incubation controller, or 0 if no controller has been set.
void setIncubationController(QQmlIncubationController *)
Sets the engine's incubation controller.
The QQmlError class encapsulates a QML error.
Definition qqmlerror.h:18
static QQuickGraphicsDevice fromRhi(QRhi *rhi)
virtual void itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF &)
static QQuickItemPrivate * get(QQuickItem *item)
The QQuickItem class provides the most basic of all visual items in \l {Qt Quick}.
Definition qquickitem.h:63
void setSize(const QSizeF &size)
void setParentItem(QQuickItem *parent)
void setHeight(qreal)
qreal width
This property holds the width of this item.
Definition qquickitem.h:75
qreal height
This property holds the height of this item.
Definition qquickitem.h:76
void setWidth(qreal)
static QQuickRenderControlPrivate * get(QQuickRenderControl *renderControl)
The QQuickRenderControl class provides a mechanism for rendering the Qt Quick scenegraph onto an offs...
bool initialize()
Initializes the scene graph resources.
void endFrame()
Specifies the end of a graphics frame.
void render()
Renders the scenegraph using the current context.
void beginFrame()
Specifies the start of a graphics frame.
void polishItems()
This function should be called as late as possible before sync().
bool sync()
This function is used to synchronize the QML scene with the rendering scene graph.
void invalidate()
Stop rendering and release resources.
static QQuickRenderTarget fromRhiRenderTarget(QRhiRenderTarget *renderTarget)
void setVisible(bool visible) override
QQuickWidgetOffscreenWindow(QQuickWindowPrivate &dd, QQuickRenderControl *control)
QSize rootObjectSize() const
QBasicTimer resizetimer
QImage grabFramebuffer() override
QQuickRenderControl * renderControl
void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &oldGeometry) override
void handleContextCreationFailure(const QSurfaceFormat &format)
QPointer< QQuickItem > root
void ensureEngine() const
void init(QQmlEngine *e=nullptr)
QQmlComponent * component
QPlatformTextureList::Flags textureListFlags() override
QRhiTexture * outputTexture
TextureData texture() const override
QBackingStoreRhiSupport offscreenRenderer
QPlatformBackingStoreRhiConfig rhiConfig() const override
QPointer< QQmlEngine > engine
QQuickWindow * offscreenWindow
void setRootObject(QObject *)
void render(bool needsSync)
QQuickWidget::ResizeMode resizeMode
bool isRenderWindow(const QWindow *w) override
QQuickWidgetRenderControl(QQuickWidget *quickwidget)
QWindow * renderWindow(QPoint *offset) override
Reimplemented in subclasses to return the real window this render control is rendering into.
The QQuickWidget class provides a widget for displaying a Qt Quick user interface.
QList< QQmlError > errors() const
Return the list of errors that occurred during the last compile or create operation.
QQuickWindow * quickWindow() const
Status status
The component's current \l{QQuickWidget::Status} {status}.
void setFormat(const QSurfaceFormat &format)
Sets the surface format for the context and offscreen surface used by this widget.
void setSource(const QUrl &)
Sets the source to the url, loads the QML component and instantiates it.
QUrl source
The URL of the source of the QML component.
QQmlEngine * engine() const
Returns a pointer to the QQmlEngine used for instantiating QML Components.
void showEvent(QShowEvent *) override
\reimp
ResizeMode
This enum specifies how to resize the view.
QSurfaceFormat format() const
Returns the actual surface format.
void mouseReleaseEvent(QMouseEvent *) override
\reimp
void mousePressEvent(QMouseEvent *) override
\reimp
void focusInEvent(QFocusEvent *event) override
\reimp
void keyReleaseEvent(QKeyEvent *) override
\reimp
void hideEvent(QHideEvent *) override
\reimp
void setResizeMode(ResizeMode)
void timerEvent(QTimerEvent *) override
void sceneGraphError(QQuickWindow::SceneGraphError error, const QString &message)
This signal is emitted when an error occurred during scene graph initialization.
~QQuickWidget() override
Destroys the QQuickWidget.
void focusOutEvent(QFocusEvent *event) override
\reimp
void setContent(const QUrl &url, QQmlComponent *component, QObject *item)
void resizeEvent(QResizeEvent *) override
void statusChanged(QQuickWidget::Status)
This signal is emitted when the component's current status changes.
QQuickItem * rootObject() const
Returns the view's root \l {QQuickItem} {item}.
void paintEvent(QPaintEvent *event) override
\reimp
Status
Specifies the loading status of the QQuickWidget.
void keyPressEvent(QKeyEvent *) override
\reimp
QQmlContext * rootContext() const
This function returns the root of the context hierarchy.
QSize sizeHint() const override
ResizeMode resizeMode
Determines whether the view should resize the window contents.
void setClearColor(const QColor &color)
Sets the clear color.
QImage grabFramebuffer() const
Renders a frame and reads it back into an image.
QQuickWidget(QWidget *parent=nullptr)
Constructs a QQuickWidget with a default QML engine as a child of parent.
bool focusNextPrevChild(bool next) override
\reimp
bool event(QEvent *) override
\reimp
void mouseDoubleClickEvent(QMouseEvent *) override
\reimp
QSize initialSize() const
Returns the initial size of the root object.
void mouseMoveEvent(QMouseEvent *) override
\reimp
QQuickGraphicsConfiguration graphicsConfig
static QQuickWindowPrivate * get(QQuickWindow *c)
QSGRenderer * renderer
static void rhiCreationFailureMessage(const QString &backendName, QString *translatedMessage, QString *untranslatedMessage)
\qmltype Window \instantiates QQuickWindow \inqmlmodule QtQuick
QQuickItem * contentItem
\qmlattachedproperty Item Window::contentItem
\inmodule QtCore\reentrant
Definition qrect.h:484
The QRegion class specifies a clip region for a painter.
Definition qregion.h:27
void swap(QRegion &other) noexcept
Definition qregion.h:42
bool isEmpty() const
Returns true if the region is empty; otherwise returns false.
The QResizeEvent class contains event parameters for resize events.
Definition qevent.h:548
const QSize & size() const
Returns the new size of the widget.
Definition qevent.h:553
\inmodule QtGui
Definition qrhi.h:576
void setTexture(QRhiTexture *tex)
Sets the texture tex.
Definition qrhi.h:583
void setRenderBuffer(QRhiRenderBuffer *rb)
Sets the renderbuffer rb.
Definition qrhi.h:586
void setResolveTexture(QRhiTexture *tex)
Sets the resolve texture tex.
Definition qrhi.h:595
\inmodule QtGui
Definition qrhi.h:1651
\inmodule QtGui
Definition qrhi.h:777
\inmodule QtGui
Definition qrhi.h:1731
@ UsedAsTransferSource
Definition qrhi.h:902
@ RenderTarget
Definition qrhi.h:898
\inmodule QtGuiPrivate \inheaderfile rhi/qrhi.h
Definition qrhi.h:1804
FrameOpResult endOffscreenFrame(EndFrameFlags flags={})
Ends, submits, and waits for the offscreen frame.
Definition qrhi.cpp:10912
bool makeThreadLocalNativeContextCurrent()
With OpenGL this makes the OpenGL context current on the current thread.
Definition qrhi.cpp:10158
bool isYUpInFramebuffer() const
Definition qrhi.cpp:10030
Implementation backend() const
Definition qrhi.cpp:8651
FrameOpResult beginOffscreenFrame(QRhiCommandBuffer **cb, BeginFrameFlags flags={})
Starts a new offscreen frame.
Definition qrhi.cpp:10893
const char * backendName() const
Definition qrhi.cpp:8683
void addCleanupCallback(const CleanupCallback &callback)
Registers a callback that is invoked either when the QRhi is destroyed, or when runCleanup() is calle...
Definition qrhi.cpp:8809
@ MultisampleRenderBuffer
Definition qrhi.h:1833
QRhiResourceUpdateBatch * nextResourceUpdateBatch()
Definition qrhi.cpp:9252
GraphicsApi
\value Unknown An unknown graphics API is in use \value Software The Qt Quick 2D Renderer is in use \...
static int chooseSampleCount(int samples, QRhi *rhi)
void setCurrentPaintDevice(QPaintDevice *device)
The QScreen class is used to query screen properties. \inmodule QtGui.
Definition qscreen.h:32
The QShowEvent class provides an event that is sent when a widget is shown.
Definition qevent.h:578
QPointF globalPosition() const
Returns the position of the point in this event on the screen or virtual desktop.
Definition qevent.h:123
QPointF position() const
Returns the position of the point in this event, relative to the widget or item that received the eve...
Definition qevent.h:119
Qt::MouseButton button() const
Returns the button that caused the event.
Definition qevent.h:116
Qt::MouseButtons buttons() const
Returns the button state when the event was generated.
Definition qevent.h:117
\inmodule QtCore
Definition qsize.h:208
constexpr QSize toSize() const noexcept
Returns an integer based copy of this size.
Definition qsize.h:401
\inmodule QtCore
Definition qsize.h:25
constexpr void setWidth(int w) noexcept
Sets the width to the given width.
Definition qsize.h:136
constexpr bool isEmpty() const noexcept
Returns true if either of the width and height is less than or equal to 0; otherwise returns false.
Definition qsize.h:124
constexpr void setHeight(int h) noexcept
Sets the height to the given height.
Definition qsize.h:139
constexpr bool isValid() const noexcept
Returns true if both the width and height is equal to or greater than 0; otherwise returns false.
Definition qsize.h:127
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5871
The QSurfaceFormat class represents the format of a QSurface. \inmodule QtGui.
void setDepthBufferSize(int size)
Set the minimum depth buffer size to size.
\inmodule QtCore
Definition qcoreevent.h:366
int timerId() const
Returns the unique timer identifier, which is the same identifier as returned from QObject::startTime...
Definition qcoreevent.h:370
The QTransform class specifies 2D transformations of a coordinate system.
Definition qtransform.h:20
QTransform & scale(qreal sx, qreal sy)
Scales the coordinate system by sx horizontally and sy vertically, and returns a reference to the mat...
\inmodule QtCore
Definition qurl.h:94
static QWidgetPrivate * get(QWidget *w)
Definition qwidget_p.h:212
QRhi * rhi() const
Definition qwidget.cpp:1030
void setRenderToTexture()
Definition qwidget_p.h:610
virtual QPlatformTextureList::Flags textureListFlags()
Definition qwidget_p.h:599
The QWidget class is the base class of all user interface objects.
Definition qwidget.h:99
QWidget * window() const
Returns the window for this widget, i.e.
Definition qwidget.cpp:4313
QSize size
the size of the widget excluding any window frame
Definition qwidget.h:113
QPointF mapToGlobal(const QPointF &) const
Translates the widget coordinate pos to global screen coordinates.
int height
the height of the widget excluding any window frame
Definition qwidget.h:115
QRect rect
the internal geometry of the widget excluding any window frame
Definition qwidget.h:116
virtual void enterEvent(QEnterEvent *event)
This event handler can be reimplemented in a subclass to receive widget enter events which are passed...
Definition qwidget.cpp:9715
void update()
Updates the widget unless updates are disabled or the widget is hidden.
QWindow * windowHandle() const
If this is a native widget, return the associated QWindow.
Definition qwidget.cpp:2483
bool event(QEvent *event) override
This is the main event handler; it handles event event.
Definition qwidget.cpp:8866
Qt::WindowStates windowState() const
Returns the current window state.
Definition qwidget.cpp:2888
QScreen * screen() const
Returns the screen the widget is on.
Definition qwidget.cpp:2496
QWindow::Visibility visibility
Definition qwindow_p.h:125
\inmodule QtGui
Definition qwindow.h:63
void setWidth(int arg)
Definition qwindow.cpp:1687
void focusObjectChanged(QObject *object)
This signal is emitted when the final receiver of events tied to focus is changed to object.
void setTitle(const QString &)
Definition qwindow.cpp:1030
void setHeight(int arg)
Definition qwindow.cpp:1696
#define this
Definition dialogs.cpp:9
void statusChanged(QQmlComponent::Status status)
[1]
Definition qlogging.cpp:11
short next
Definition keywords.cpp:445
Combined button and popup list for selecting options.
WindowState
Definition qnamespace.h:251
@ WindowFullScreen
Definition qnamespace.h:255
@ WindowNoState
Definition qnamespace.h:252
@ WindowMinimized
Definition qnamespace.h:253
@ WindowMaximized
Definition qnamespace.h:254
@ ImAnchorRectangle
@ ImInputItemClipRectangle
@ ImCursorPosition
@ ImCursorRectangle
@ WA_AcceptTouchEvents
Definition qnamespace.h:404
@ WA_Resized
Definition qnamespace.h:308
@ PreciseTimer
@ StrongFocus
Definition qnamespace.h:110
@ Key_Tab
Definition qnamespace.h:664
@ Key_Backtab
Definition qnamespace.h:665
@ NoModifier
@ AA_ShareOpenGLContexts
Definition qnamespace.h:447
QTextStream & endl(QTextStream &stream)
Writes '\n' to the stream and flushes the stream.
DBusConnection const char DBusError * error
EGLConfig config
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
Definition qfloat16.h:333
#define qGuiApp
#define qWarning
Definition qlogging.h:166
#define qFatal
Definition qlogging.h:168
return ret
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
#define SLOT(a)
Definition qobjectdefs.h:52
#define SIGNAL(a)
Definition qobjectdefs.h:53
GLsizei samples
GLenum mode
GLfloat GLfloat GLfloat w
[0]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLint GLsizei width
GLuint color
[2]
GLbitfield flags
GLenum GLuint GLintptr offset
GLint GLsizei GLsizei GLenum format
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei imageSize
GLsizei GLsizei GLchar * source
struct _cl_event * event
GLuint GLenum GLenum transform
GLhandleARB obj
[2]
GLenum query
GLuint res
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLuint64EXT * result
[6]
GLfloat GLfloat p
[1]
GLuint * states
static qreal component(const QPointF &point, unsigned int i)
QQuickItem * qobject_cast< QQuickItem * >(QObject *o)
Definition qquickitem.h:492
#define Q_QUICK_INPUT_PROFILE(Type, DetailType, A, B)
static void remapInputMethodQueryEvent(QObject *object, QInputMethodQueryEvent *e)
static QPlatformBackingStoreRhiConfig::Api graphicsApiToBackingStoreRhiApi(QSGRendererInterface::GraphicsApi api)
static Qt::WindowState resolveWindowState(Qt::WindowStates states)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
SSL_CTX int(* cb)(SSL *ssl, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
#define qPrintable(string)
Definition qstring.h:1531
QLatin1StringView QLatin1String
Definition qstringfwd.h:31
#define emit
unsigned char uchar
Definition qtypes.h:32
QUrl url("example.com")
[constructor-url-reference]
QObject::connect nullptr
myObject disconnect()
[26]
QGraphicsScene scene
[0]
QGraphicsItem * item
QPainter painter(this)
[7]
QNetworkRequestFactory api
[0]
QNetworkProxy proxy
[0]
QQuickView * view
[0]
QJSEngine engine
[0]
\inmodule QtGui
Definition qrhi.h:1723