Qt 6.x
The Qt SDK
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
51
53:QQuickWindow(dd, control)
54{
55 setTitle(QString::fromLatin1("Offscreen"));
56 setObjectName(QString::fromLatin1("QQuickWidgetOffscreenWindow"));
57}
58
59// override setVisble to prevent accidental offscreen window being created
60// by base class.
62public:
63 void setVisible(bool visible) override {
64 Q_Q(QWindow);
65 // this stays always invisible
66 visibility = visible ? QWindow::Windowed : QWindow::Hidden;
67 q->visibilityChanged(visibility); // workaround for QTBUG-49054
68 }
69};
70
72
74{
75 Q_DECLARE_PRIVATE(QQuickWidgetRenderControl)
76public:
79
80};
81
83{
84public:
85 Q_DECLARE_PUBLIC(QQuickWidgetRenderControl)
87 : QQuickRenderControlPrivate(renderControl)
88 , m_quickWidget(qqw)
89 {
90 }
91
92 bool isRenderWindow(const QWindow *w) override {
93#if QT_CONFIG(graphicsview)
95 auto *proxy = (widgetd && widgetd->extra) ? widgetd->extra->proxyWidget : nullptr;
96 auto *scene = proxy ? proxy->scene() : nullptr;
97 if (scene) {
98 for (const auto &view : scene->views()) {
99 if (view->window()->windowHandle() == w)
100 return true;
101 }
102 }
103
104 return m_quickWidget->window()->windowHandle() == w;
105#endif
106 }
108};
109
112{
113}
114
116{
118 if (offset)
119 *offset = d->m_quickWidget->mapTo(d->m_quickWidget->window(), QPoint());
120
121 QWindow *result = nullptr;
122#if QT_CONFIG(graphicsview)
123 QWidgetPrivate *widgetd = QWidgetPrivate::get(d->m_quickWidget);
124 if (widgetd->extra) {
125 if (auto proxy = widgetd->extra->proxyWidget) {
126 auto scene = proxy->scene();
127 if (scene) {
128 const auto views = scene->views();
129 if (!views.isEmpty()) {
130 // Get the first QGV containing the proxy. Not ideal, but the callers
131 // of this function aren't prepared to handle more than one render window.
132 auto candidateView = views.first();
133 result = candidateView->window()->windowHandle();
134 }
135 }
136 }
137 }
138#endif
139 if (!result)
140 result = d->m_quickWidget->window()->windowHandle();
141
142 return result;
143}
144
146{
147 Q_Q(QQuickWidget);
148
150 offscreenWindow->setScreen(q->screen());
151 // Do not call create() on offscreenWindow.
152
153 QWidget::connect(offscreenWindow, SIGNAL(sceneGraphInitialized()), q, SLOT(createFramebufferObject()));
154 QWidget::connect(offscreenWindow, SIGNAL(sceneGraphInvalidated()), q, SLOT(destroyFramebufferObject()));
155 QWidget::connect(offscreenWindow, &QQuickWindow::focusObjectChanged, q, &QQuickWidget::propagateFocusObjectChanged);
156
157#if QT_CONFIG(accessibility)
158 QAccessible::installFactory(&qAccessibleQuickWidgetFactory);
159#endif
160}
161
163{
164 // This should initialize, if not already done, the absolute minimum set of
165 // mandatory backing resources, meaning the QQuickWindow and its
166 // QQuickRenderControl. This function may be called very early on upon
167 // construction, including before init() even.
168
169 Q_Q(QQuickWidget);
170 if (!renderControl)
172 if (!offscreenWindow)
174
175 // Check if the Software Adaptation is being used
176 auto sgRendererInterface = offscreenWindow->rendererInterface();
177 if (sgRendererInterface && sgRendererInterface->graphicsApi() == QSGRendererInterface::Software)
178 useSoftwareRenderer = true;
179}
180
182{
183 Q_Q(QQuickWidget);
184
186
187 if (!useSoftwareRenderer) {
190 else
191 qWarning("QQuickWidget is not supported on this platform.");
192 }
193
194 engine = e;
195
197 engine.data()->setIncubationController(offscreenWindow->incubationController());
198
199#if QT_CONFIG(quick_draganddrop)
200 q->setAcceptDrops(true);
201#endif
202
203 QObject::connect(renderControl, SIGNAL(renderRequested()), q, SLOT(triggerUpdate()));
204 QObject::connect(renderControl, SIGNAL(sceneChanged()), q, SLOT(triggerUpdate()));
205}
206
208{
209 Q_Q(const QQuickWidget);
210 if (!engine.isNull())
211 return;
212
213 engine = new QQmlEngine(const_cast<QQuickWidget*>(q));
214 engine.data()->setIncubationController(offscreenWindow->incubationController());
215}
216
218{
219 if (!useSoftwareRenderer && rhi) {
220 // For the user's own OpenGL code connected to some QQuickWindow signals.
222 }
223
225}
226
228{
229 Q_Q(QQuickWidget);
230
231 if (offscreenWindow->isPersistentSceneGraph()
232 && qGuiApp->testAttribute(Qt::AA_ShareOpenGLContexts)
234 {
235 return;
236 }
237
238 // In case of !isPersistentSceneGraph or when we need a new context due to
239 // the need to share resources with the new window's context, we must both
240 // invalidate the scenegraph and destroy the context. QQuickRenderControl
241 // must be recreated because its RHI will contain a dangling pointer to
242 // the context.
243
244 QScopedPointer<QQuickWindow> oldOffScreenWindow(offscreenWindow); // Do not delete before reparenting sgItem
245 offscreenWindow = nullptr;
246 delete renderControl;
247
250
251 QObject::connect(renderControl, SIGNAL(renderRequested()), q, SLOT(triggerUpdate()));
252 QObject::connect(renderControl, SIGNAL(sceneChanged()), q, SLOT(triggerUpdate()));
253
254 if (!source.isEmpty())
255 execute();
256 else if (QQuickItem *sgItem = qobject_cast<QQuickItem *>(root))
257 sgItem->setParentItem(offscreenWindow->contentItem());
258}
259
261 : root(nullptr)
263 , offscreenWindow(nullptr)
264 , renderControl(nullptr)
265 , rhi(nullptr)
266 , outputTexture(nullptr)
267 , depthStencil(nullptr)
268 , msaaBuffer(nullptr)
269 , rt(nullptr)
270 , rtRp(nullptr)
271 , resizeMode(QQuickWidget::SizeViewToRootObject)
272 , initialSize(0,0)
273 , eventPending(false)
274 , updatePending(false)
275 , fakeHidden(false)
276 , requestedSamples(0)
277 , useSoftwareRenderer(false)
278 , forceFullUpdate(false)
279 , deviceLost(false)
280{
281}
282
284{
285 Q_Q(QQuickWidget);
287 q->destroyFramebufferObject();
288 delete offscreenWindow;
289 delete renderControl;
291}
292
294{
295 Q_Q(QQuickWidget);
296 ensureEngine();
297
298 if (root) {
299 delete root;
300 root = nullptr;
301 }
302 if (component) {
303 delete component;
304 component = nullptr;
305 }
306 if (!source.isEmpty()) {
308 if (!component->isLoading()) {
309 q->continueExecute();
310 } else {
312 q, SLOT(continueExecute()));
313 }
314 }
315}
316
318 const QRectF &oldGeometry)
319{
320 Q_Q(QQuickWidget);
321 if (resizeItem == root && resizeMode == QQuickWidget::SizeViewToRootObject) {
322 // wait for both width and height to be changed
324 }
325 QQuickItemChangeListener::itemGeometryChanged(resizeItem, change, oldGeometry);
326}
327
328void QQuickWidgetPrivate::render(bool needsSync)
329{
330 Q_Q(QQuickWidget);
331 if (!useSoftwareRenderer) {
332 if (deviceLost) {
333 deviceLost = false;
335 q->createFramebufferObject();
336 }
337
338 if (!rhi) {
339 qWarning("QQuickWidget: Attempted to render scene with no rhi");
340 return;
341 }
342
343 // createFramebufferObject() bails out when the size is empty. In this case
344 // we cannot render either.
345 if (!outputTexture)
346 return;
347
351 // graphics resources controlled by us must be released
353 // skip this round and hope that the tlw's repaint manager will manage to reinitialize
354 deviceLost = true;
355 return;
356 }
358 qWarning("QQuickWidget: Failed to begin recording a frame");
359 return;
360 }
361
362 if (needsSync) {
365 }
366
368
370 } else {
371 //Software Renderer
372 if (needsSync) {
375 }
376 if (!offscreenWindow)
377 return;
379 auto softwareRenderer = static_cast<QSGSoftwareRenderer*>(cd->renderer);
380 if (softwareRenderer && !softwareImage.isNull()) {
381 softwareRenderer->setCurrentPaintDevice(&softwareImage);
382 if (forceFullUpdate) {
383 softwareRenderer->markDirty();
384 forceFullUpdate = false;
385 }
387
388 updateRegion += softwareRenderer->flushRegion();
389 }
390 }
391}
392
394{
395 Q_Q(QQuickWidget);
396 updatePending = false;
397
398 if (!q->isVisible() || fakeHidden)
399 return;
400
401 render(true);
402
403#if QT_CONFIG(graphicsview)
404 if (q->window()->graphicsProxyWidget())
405 QWidgetPrivate::nearestGraphicsProxyWidget(q)->update();
406 else
407#endif
408 {
410 q->update(); // schedule composition
411 else if (!updateRegion.isEmpty())
412 q->update(updateRegion);
413 }
414}
415
417{
418 if (!useSoftwareRenderer && !rhi)
419 return QImage();
420
421 // grabWindow() does not work for the rhi case, we are in control of the
422 // render target, and so it is up to us to read it back. When the software
423 // renderer is in use, just call grabWindow().
424
425 if (outputTexture) {
426 render(true);
427 QRhiCommandBuffer *cb = nullptr;
430 QRhiReadbackResult readResult;
432 cb->resourceUpdate(resUpd);
434 if (!readResult.data.isEmpty()) {
435 QImage wrapperImage(reinterpret_cast<const uchar *>(readResult.data.constData()),
436 readResult.pixelSize.width(), readResult.pixelSize.height(),
438 if (rhi->isYUpInFramebuffer())
439 return wrapperImage.mirrored();
440 else
441 return wrapperImage.copy();
442 }
443 return QImage();
444 }
445
446 return offscreenWindow->grabWindow();
447}
448
449// Intentionally not overriding the QQuickWindow's focusObject.
450// Key events should go to our key event handlers, and then to the
451// QQuickWindow, not any in-scene item.
452
611 : QWidget(*(new QQuickWidgetPrivate), parent, {})
612{
613 setMouseTracking(true);
614 setFocusPolicy(Qt::StrongFocus);
616 d_func()->init();
617}
618
626{
628}
629
640 : QWidget(*(new QQuickWidgetPrivate), parent, {})
641{
642 setMouseTracking(true);
643 setFocusPolicy(Qt::StrongFocus);
644 d_func()->init(engine);
645}
646
651{
652 // Ensure that the component is destroyed before the engine; the engine may
653 // be a child of the QQuickWidgetPrivate, and will be destroyed by its dtor
654 Q_D(QQuickWidget);
655 delete d->root;
656 d->root = nullptr;
657
658 // NB! resetting graphics resources must be done from this destructor,
659 // *not* from the private class' destructor. This is due to how destruction
660 // works and due to the QWidget dtor (for toplevels) destroying the repaint
661 // manager and rhi before the (QObject) private gets destroyed. Hence must
662 // do it here early on.
663 d->destroy();
664}
665
687{
688 Q_D(QQuickWidget);
689 d->source = url;
690 d->execute();
691}
692
699{
700 Q_D(QQuickWidget);
701 d->source = url;
702 d->component = component;
703
704 if (d->component && d->component->isError()) {
705 const QList<QQmlError> errorList = d->component->errors();
706 for (const QQmlError &error : errorList) {
707 QMessageLogger(error.url().toString().toLatin1().constData(), error.line(), nullptr).warning()
708 << error;
709 }
711 return;
712 }
713
714 d->setRootObject(item);
716}
717
724{
725 Q_D(const QQuickWidget);
726 return d->source;
727}
728
734{
735 Q_D(const QQuickWidget);
736 d->ensureEngine();
737 return const_cast<QQmlEngine *>(d->engine.data());
738}
739
748{
749 Q_D(const QQuickWidget);
750 d->ensureEngine();
751 return d->engine.data()->rootContext();
752}
753
794{
795 Q_D(const QQuickWidget);
796 if (!d->engine && !d->source.isEmpty())
797 return QQuickWidget::Error;
798
799 if (!d->component)
800 return QQuickWidget::Null;
801
802 if (d->component->status() == QQmlComponent::Ready && !d->root)
803 return QQuickWidget::Error;
804
805 return QQuickWidget::Status(d->component->status());
806}
807
815{
816 Q_D(const QQuickWidget);
817 QList<QQmlError> errs;
818
819 if (d->component)
820 errs = d->component->errors();
821
822 if (!d->engine && !d->source.isEmpty()) {
824 error.setDescription(QLatin1String("QQuickWidget: invalid qml engine."));
825 errs << error;
826 }
827 if (d->component && d->component->status() == QQmlComponent::Ready && !d->root) {
829 error.setDescription(QLatin1String("QQuickWidget: invalid root object."));
830 errs << error;
831 }
832
833 return errs;
834}
835
854{
855 Q_D(QQuickWidget);
856 if (d->resizeMode == mode)
857 return;
858
859 if (d->root) {
860 if (d->resizeMode == SizeViewToRootObject) {
862 p->removeItemChangeListener(d, QQuickItemPrivate::Geometry);
863 }
864 }
865
866 d->resizeMode = mode;
867 if (d->root) {
868 d->initResize();
869 }
870}
871
873{
874 if (root) {
877 p->addItemChangeListener(this, QQuickItemPrivate::Geometry);
878 }
879 }
880 updateSize();
881}
882
884{
885 Q_Q(QQuickWidget);
886 if (!root)
887 return;
888
890 QSize newSize = QSize(root->width(), root->height());
891 if (newSize.isValid()) {
892 if (newSize != q->size()) {
893 q->resize(newSize);
894 q->updateGeometry();
895 } else if (offscreenWindow->size().isEmpty()) {
896 // QQuickDeliveryAgentPrivate::deliverHoverEvent() ignores events that
897 // occur outside of QQuickRootItem's geometry, so we need it to match root's size.
899 }
900 }
902 const bool needToUpdateWidth = !qFuzzyCompare(q->width(), root->width());
903 const bool needToUpdateHeight = !qFuzzyCompare(q->height(), root->height());
904
905 if (needToUpdateWidth && needToUpdateHeight) {
906 // Make sure that we have realistic sizing behavior by following
907 // what on-screen windows would do and resize everything, not just
908 // the root item. We do this because other types may be relying on
909 // us to behave correctly.
910 const QSizeF newSize(q->width(), q->height());
911 offscreenWindow->resize(newSize.toSize());
913 root->setSize(newSize);
914 } else if (needToUpdateWidth) {
915 const int newWidth = q->width();
916 offscreenWindow->setWidth(newWidth);
918 root->setWidth(newWidth);
919 } else if (needToUpdateHeight) {
920 const int newHeight = q->height();
921 offscreenWindow->setHeight(newHeight);
923 root->setHeight(newHeight);
924 }
925 }
926}
927
934{
935 Q_Q(QQuickWidget);
936 if (offscreenWindow == nullptr)
937 return;
938
939 const QPoint &pos = q->mapToGlobal(QPoint(0, 0));
940 if (offscreenWindow->position() != pos)
941 offscreenWindow->setPosition(pos);
942}
943
945{
947 int widthCandidate = -1;
948 int heightCandidate = -1;
949 if (root) {
950 widthCandidate = root->width();
951 heightCandidate = root->height();
952 }
953 if (widthCandidate > 0) {
954 rootObjectSize.setWidth(widthCandidate);
955 }
956 if (heightCandidate > 0) {
957 rootObjectSize.setHeight(heightCandidate);
958 }
959 return rootObjectSize;
960}
961
963{
964 Q_Q(QQuickWidget);
965
966 QString translatedMessage;
967 QString untranslatedMessage;
968 QQuickWindowPrivate::rhiCreationFailureMessage(QLatin1String("QRhi"), &translatedMessage, &untranslatedMessage);
969
971 const bool signalConnected = q->isSignalConnected(errorSignal);
972 if (signalConnected)
973 emit q->sceneGraphError(QQuickWindow::ContextNotAvailable, translatedMessage);
974
975#if defined(Q_OS_WIN) && QT_CONFIG(messagebox)
976 if (!signalConnected && !QLibraryInfo::isDebugBuild() && !GetConsoleWindow())
978#endif // Q_OS_WIN
979 if (!signalConnected)
980 qFatal("%s", qPrintable(untranslatedMessage));
981}
982
984{
985 switch (api) {
994 default:
996 }
997}
998
999// Never called by Software Rendering backend
1001{
1002 Q_Q(QQuickWidget);
1003
1004 QWidgetPrivate *tlwd = QWidgetPrivate::get(q->window());
1005 // when reparenting, the rhi may suddenly be different
1006 if (rhi) {
1007 QRhi *tlwRhi = nullptr;
1008 if (QWidgetRepaintManager *repaintManager = tlwd->maybeRepaintManager())
1009 tlwRhi = repaintManager->rhi();
1010 if (tlwRhi && rhi != tlwRhi)
1011 rhi = nullptr;
1012 }
1013
1014 // On hide-show we may invalidate() (when !isPersistentSceneGraph) but our
1015 // context is kept. We may need to initialize() again, though.
1016 const bool onlyNeedsSgInit = rhi && !offscreenWindow->isSceneGraphInitialized();
1017
1018 if (!onlyNeedsSgInit) {
1019 if (rhi)
1020 return;
1021
1022 if (QWidgetRepaintManager *repaintManager = tlwd->maybeRepaintManager())
1023 rhi = repaintManager->rhi();
1024
1025 if (!rhi) {
1026 // The widget (and its parent chain, if any) may not be shown at
1027 // all, yet one may still want to use it for grabs. This is
1028 // ridiculous of course because the rendering infrastructure is
1029 // tied to the top-level widget that initializes upon expose, but
1030 // it has to be supported.
1032 offscreenRenderer.setFormat(q->format());
1033 // no window passed in, so no swapchain, but we get a functional QRhi which we own
1036 }
1037
1038 // Could be that something else already initialized the window with some
1039 // other graphics API for the QRhi, that's not good.
1040 if (rhi && rhi->backend() != QBackingStoreRhiSupport::apiToRhiBackend(graphicsApiToBackingStoreRhiApi(QQuickWindow::graphicsApi()))) {
1041 qWarning("The top-level window is not using the expected graphics API for composition, "
1042 "'%s' is not compatible with this QQuickWidget",
1043 rhi->backendName());
1044 rhi = nullptr;
1045 }
1046 }
1047
1048 if (rhi) {
1049 if (!offscreenWindow->isSceneGraphInitialized()) {
1051#if QT_CONFIG(vulkan)
1052 if (QWindow *w = q->window()->windowHandle())
1053 offscreenWindow->setVulkanInstance(w->vulkanInstance());
1054#endif
1056 }
1057 } else {
1058 qWarning("QQuickWidget: Failed to get a QRhi from the top-level widget's window");
1059 }
1060}
1061
1062void QQuickWidget::createFramebufferObject()
1063{
1064 Q_D(QQuickWidget);
1065
1066 // Could come from Show -> initializeWithRhi -> sceneGraphInitialized in which case the size may
1067 // still be invalid on some platforms. Bail out. A resize will come later on.
1068 if (size().isEmpty())
1069 return;
1070
1071 // Even though this is just an offscreen window we should set the position on it, as it might be
1072 // useful for an item to know the actual position of the scene.
1073 // Note: The position will be update when we get a move event (see: updatePosition()).
1074 const QPoint &globalPos = mapToGlobal(QPoint(0, 0));
1075 d->offscreenWindow->setGeometry(globalPos.x(), globalPos.y(), width(), height());
1076
1077 if (d->useSoftwareRenderer) {
1078 const QSize imageSize = size() * devicePixelRatio();
1080 d->softwareImage.setDevicePixelRatio(devicePixelRatio());
1081 d->forceFullUpdate = true;
1082 return;
1083 }
1084
1085 if (!d->rhi) {
1086 qWarning("QQuickWidget: Attempted to create output texture with no QRhi");
1087 return;
1088 }
1089
1090 int samples = d->requestedSamples;
1091 if (d->rhi->isFeatureSupported(QRhi::MultisampleRenderBuffer))
1093 else
1094 samples = 0;
1095
1096 const QSize fboSize = size() * devicePixelRatio();
1097
1098 // Could be a simple hide - show, in which case the previous texture is just fine.
1099 if (!d->outputTexture) {
1100 d->outputTexture = d->rhi->newTexture(QRhiTexture::RGBA8, fboSize, 1, QRhiTexture::RenderTarget);
1101 if (!d->outputTexture->create()) {
1102 qWarning("QQuickWidget: failed to create output texture of size %dx%d",
1103 fboSize.width(), fboSize.height());
1104 }
1105 }
1106 if (!d->depthStencil) {
1107 d->depthStencil = d->rhi->newRenderBuffer(QRhiRenderBuffer::DepthStencil, fboSize, samples);
1108 if (!d->depthStencil->create()) {
1109 qWarning("QQuickWidget: failed to create depth/stencil buffer of size %dx%d and sample count %d",
1110 fboSize.width(), fboSize.height(), samples);
1111 }
1112 }
1113 if (samples > 1 && !d->msaaBuffer) {
1114 d->msaaBuffer = d->rhi->newRenderBuffer(QRhiRenderBuffer::Color, fboSize, samples);
1115 if (!d->msaaBuffer->create()) {
1116 qWarning("QQuickWidget: failed to create multisample renderbuffer of size %dx%d and sample count %d",
1117 fboSize.width(), fboSize.height(), samples);
1118 }
1119 }
1120 if (!d->rt) {
1122 QRhiColorAttachment colorAtt;
1123 if (samples <= 1) {
1124 colorAtt.setTexture(d->outputTexture);
1125 } else {
1126 colorAtt.setRenderBuffer(d->msaaBuffer);
1127 colorAtt.setResolveTexture(d->outputTexture);
1128 }
1129 rtDesc.setColorAttachments({ colorAtt });
1130 rtDesc.setDepthStencilBuffer(d->depthStencil);
1131 d->rt = d->rhi->newTextureRenderTarget(rtDesc);
1132 d->rtRp = d->rt->newCompatibleRenderPassDescriptor();
1133 d->rt->setRenderPassDescriptor(d->rtRp);
1134 d->rt->create();
1135 }
1136 if (d->outputTexture->pixelSize() != fboSize) {
1137 d->outputTexture->setPixelSize(fboSize);
1138 if (!d->outputTexture->create()) {
1139 qWarning("QQuickWidget: failed to create resized output texture of size %dx%d",
1140 fboSize.width(), fboSize.height());
1141 }
1142 d->depthStencil->setPixelSize(fboSize);
1143 if (!d->depthStencil->create()) {
1144 qWarning("QQuickWidget: failed to create resized depth/stencil buffer of size %dx%d",
1145 fboSize.width(), fboSize.height());
1146 }
1147 if (d->msaaBuffer) {
1148 d->msaaBuffer->setPixelSize(fboSize);
1149 if (!d->msaaBuffer->create()) {
1150 qWarning("QQuickWidget: failed to create resized multisample renderbuffer of size %dx%d",
1151 fboSize.width(), fboSize.height());
1152 }
1153 }
1154 }
1155
1156 d->offscreenWindow->setRenderTarget(QQuickRenderTarget::fromRhiRenderTarget(d->rt));
1157
1158 d->renderControl->setSamples(samples);
1159
1160 // Sanity check: The window must not have an underlying platform window.
1161 // Having one would mean create() was called and platforms that only support
1162 // a single native window were in trouble.
1163 Q_ASSERT(!d->offscreenWindow->handle());
1164}
1165
1166void QQuickWidget::destroyFramebufferObject()
1167{
1168 Q_D(QQuickWidget);
1169
1170 if (d->useSoftwareRenderer) {
1171 d->softwareImage = QImage();
1172 return;
1173 }
1174
1175 delete d->rt;
1176 d->rt = nullptr;
1177 delete d->rtRp;
1178 d->rtRp = nullptr;
1179 delete d->depthStencil;
1180 d->depthStencil = nullptr;
1181 delete d->msaaBuffer;
1182 d->msaaBuffer = nullptr;
1183 delete d->outputTexture;
1184 d->outputTexture = nullptr;
1185}
1186
1188{
1189 Q_D(const QQuickWidget);
1190 return d->resizeMode;
1191}
1192
1196void QQuickWidget::continueExecute()
1197{
1198 Q_D(QQuickWidget);
1199 disconnect(d->component, SIGNAL(statusChanged(QQmlComponent::Status)), this, SLOT(continueExecute()));
1200
1201 if (d->component->isError()) {
1202 const QList<QQmlError> errorList = d->component->errors();
1203 for (const QQmlError &error : errorList) {
1204 QMessageLogger(error.url().toString().toLatin1().constData(), error.line(), nullptr).warning()
1205 << error;
1206 }
1208 return;
1209 }
1210
1211 QObject *obj = d->component->create();
1212
1213 if (d->component->isError()) {
1214 const QList<QQmlError> errorList = d->component->errors();
1215 for (const QQmlError &error : errorList) {
1216 QMessageLogger(error.url().toString().toLatin1().constData(), error.line(), nullptr).warning()
1217 << error;
1218 }
1220 return;
1221 }
1222
1223 d->setRootObject(obj);
1225}
1226
1227
1232{
1233 Q_Q(QQuickWidget);
1234 if (root == obj)
1235 return;
1236 if (QQuickItem *sgItem = qobject_cast<QQuickItem *>(obj)) {
1237 root = sgItem;
1239 } else if (qobject_cast<QWindow *>(obj)) {
1240 qWarning() << "QQuickWidget does not support using windows as a root item." << Qt::endl
1241 << Qt::endl
1242 << "If you wish to create your root window from QML, consider using QQmlApplicationEngine instead." << Qt::endl;
1243 } else {
1244 qWarning() << "QQuickWidget only supports loading of root objects that derive from QQuickItem." << Qt::endl
1245 << Qt::endl
1246 << "Ensure your QML code is written for QtQuick 2, and uses a root that is or" << Qt::endl
1247 << "inherits from QtQuick's Item (not a Timer, QtObject, etc)." << Qt::endl;
1248 delete obj;
1249 root = nullptr;
1250 }
1251 if (root) {
1253 bool resized = q->testAttribute(Qt::WA_Resized);
1254 if ((resizeMode == QQuickWidget::SizeViewToRootObject || !resized) &&
1255 initialSize != q->size()) {
1256 q->resize(initialSize);
1257 }
1258 initResize();
1259 }
1260}
1261
1263{
1264 const_cast<QQuickWidgetPrivate *>(this)->ensureBackingScene();
1266 return {};
1267
1269
1271 // This is only here to support some of the env.vars. (such as
1272 // QSG_RHI_DEBUG_LAYER). There is currently no way to set a
1273 // QQuickGraphicsConfiguration for a QQuickWidget, which means things like
1274 // the pipeline cache are just not available. That is something to support
1275 // on the widget/backingstore level since that's where the QRhi is
1276 // controlled in this case.
1277 const bool debugLayerRequested = wd->graphicsConfig.isDebugLayerEnabled();
1278 config.setDebugLayer(debugLayerRequested);
1279 return config;
1280}
1281
1283{
1284 Q_Q(const QQuickWidget);
1285 if (!q->isWindow() && q->internalWinId()) {
1286 qWarning() << "QQuickWidget cannot be used as a native child widget."
1287 << "Consider setting Qt::AA_DontCreateNativeWidgetSiblings";
1288 return {};
1289 }
1290 return { outputTexture, nullptr };
1291}
1292
1293QPlatformTextureList::Flags QQuickWidgetPrivate::textureListFlags()
1294{
1295 QPlatformTextureList::Flags flags = QWidgetPrivate::textureListFlags();
1297 return flags;
1298}
1299
1305{
1306 Q_D(QQuickWidget);
1307 if (!e || e->timerId() == d->resizetimer.timerId()) {
1308 d->updateSize();
1309 d->resizetimer.stop();
1310 } else if (e->timerId() == d->updateTimer.timerId()) {
1311 d->eventPending = false;
1312 d->updateTimer.stop();
1313 if (d->updatePending)
1314 d->renderSceneGraph();
1315 }
1316}
1317
1323{
1324 Q_D(const QQuickWidget);
1325 QSize rootObjectSize = d->rootObjectSize();
1326 if (rootObjectSize.isEmpty()) {
1327 return size();
1328 } else {
1329 return rootObjectSize;
1330 }
1331}
1332
1341{
1342 Q_D(const QQuickWidget);
1343 return d->initialSize;
1344}
1345
1352{
1353 Q_D(const QQuickWidget);
1354 return d->root;
1355}
1356
1363{
1364 Q_D(QQuickWidget);
1365 if (d->resizeMode == SizeRootObjectToView)
1366 d->updateSize();
1367
1368 if (e->size().isEmpty()) {
1369 //stop rendering
1370 d->fakeHidden = true;
1371 return;
1372 }
1373
1374 bool needsSync = false;
1375 if (d->fakeHidden) {
1376 //restart rendering
1377 d->fakeHidden = false;
1378 needsSync = true;
1379 }
1380
1381 // Software Renderer
1382 if (d->useSoftwareRenderer) {
1383 needsSync = true;
1384 if (d->softwareImage.size() != size() * devicePixelRatio()) {
1385 createFramebufferObject();
1386 }
1387 } else {
1388 if (d->rhi) {
1389 // Bail out when receiving a resize after scenegraph invalidation. This can happen
1390 // during hide - resize - show sequences and also during application exit.
1391 if (!d->outputTexture && !d->offscreenWindow->isSceneGraphInitialized())
1392 return;
1393 if (!d->outputTexture || d->outputTexture->pixelSize() != size() * devicePixelRatio()) {
1394 needsSync = true;
1395 createFramebufferObject();
1396 }
1397 } else {
1398 // This will result in a scenegraphInitialized() signal which
1399 // is connected to createFramebufferObject().
1400 needsSync = true;
1401 d->initializeWithRhi();
1402 }
1403
1404 if (!d->rhi) {
1405 qWarning("QQuickWidget::resizeEvent() no QRhi");
1406 return;
1407 }
1408 }
1409
1410 d->render(needsSync);
1411}
1412
1415{
1416 Q_D(QQuickWidget);
1418 Q_QUICK_INPUT_PROFILE(QQuickProfiler::Key, QQuickProfiler::InputKeyPress, event.key(),
1420 QCoreApplication::sendEvent(d->offscreenWindow, &event);
1421
1423 Q_QUICK_INPUT_PROFILE(QQuickProfiler::Key, QQuickProfiler::InputKeyRelease, releaseEvent.key(),
1425 QCoreApplication::sendEvent(d->offscreenWindow, &releaseEvent);
1426 return event.isAccepted();
1427}
1428
1431{
1432 Q_D(QQuickWidget);
1433 Q_QUICK_INPUT_PROFILE(QQuickProfiler::Key, QQuickProfiler::InputKeyPress, e->key(),
1434 e->modifiers());
1435
1436 QCoreApplication::sendEvent(d->offscreenWindow, e);
1437}
1438
1441{
1442 Q_D(QQuickWidget);
1443 Q_QUICK_INPUT_PROFILE(QQuickProfiler::Key, QQuickProfiler::InputKeyRelease, e->key(),
1444 e->modifiers());
1445
1446 QCoreApplication::sendEvent(d->offscreenWindow, e);
1447}
1448
1451{
1452 Q_D(QQuickWidget);
1453 Q_QUICK_INPUT_PROFILE(QQuickProfiler::Mouse, QQuickProfiler::InputMouseMove, e->position().x(),
1454 e->position().y());
1455
1456 // Put position into the event's position and scenePosition, and globalPosition into the
1457 // event's globalPosition. This way the scenePosition in e is ignored and is replaced by
1458 // position. This is necessary because QQuickWindow thinks of itself as a
1459 // top-level window always.
1460 QMouseEvent mappedEvent(e->type(), e->position(), e->position(), e->globalPosition(),
1461 e->button(), e->buttons(), e->modifiers(), e->source());
1462 QCoreApplication::sendEvent(d->offscreenWindow, &mappedEvent);
1463 e->setAccepted(mappedEvent.isAccepted());
1464}
1465
1468{
1469 Q_D(QQuickWidget);
1470 Q_QUICK_INPUT_PROFILE(QQuickProfiler::Mouse, QQuickProfiler::InputMouseDoubleClick,
1471 e->button(), e->buttons());
1472
1473 // As the second mouse press is suppressed in widget windows we emulate it here for QML.
1474 // See QTBUG-25831
1475 QMouseEvent pressEvent(QEvent::MouseButtonPress, e->position(), e->position(), e->globalPosition(),
1476 e->button(), e->buttons(), e->modifiers(), e->source());
1477 QCoreApplication::sendEvent(d->offscreenWindow, &pressEvent);
1478 e->setAccepted(pressEvent.isAccepted());
1479 QMouseEvent mappedEvent(e->type(), e->position(), e->position(), e->globalPosition(),
1480 e->button(), e->buttons(), e->modifiers(), e->source());
1481 QCoreApplication::sendEvent(d->offscreenWindow, &mappedEvent);
1482}
1483
1486{
1487 Q_D(QQuickWidget);
1488 bool shouldTriggerUpdate = true;
1489
1490 if (!d->useSoftwareRenderer) {
1491 d->initializeWithRhi();
1492
1493 if (d->offscreenWindow->isSceneGraphInitialized()) {
1494 shouldTriggerUpdate = false;
1495 d->render(true);
1496 // render() may have led to a QQuickWindow::update() call (for
1497 // example, having a scene with a QQuickFramebufferObject::Renderer
1498 // calling update() in its render()) which in turn results in
1499 // renderRequested in the rendercontrol, ending up in
1500 // triggerUpdate. In this case just calling update() is not
1501 // acceptable, we need the full renderSceneGraph issued from
1502 // timerEvent().
1503 if (!d->eventPending && d->updatePending) {
1504 d->updatePending = false;
1505 update();
1506 }
1507 }
1508 }
1509
1510 if (shouldTriggerUpdate)
1511 triggerUpdate();
1512
1513 // note offscreenWindow is "QQuickWidgetOffscreenWindow" instance
1514 d->offscreenWindow->setVisible(true);
1515 if (QQmlInspectorService *service = QQmlDebugConnector::service<QQmlInspectorService>())
1516 service->setParentWindow(d->offscreenWindow, window()->windowHandle());
1517}
1518
1521{
1522 Q_D(QQuickWidget);
1523 if (!d->offscreenWindow->isPersistentSceneGraph())
1524 d->invalidateRenderControl();
1525 // note offscreenWindow is "QQuickWidgetOffscreenWindow" instance
1526 d->offscreenWindow->setVisible(false);
1527 if (QQmlInspectorService *service = QQmlDebugConnector::service<QQmlInspectorService>())
1528 service->setParentWindow(d->offscreenWindow, d->offscreenWindow);
1529}
1530
1533{
1534 Q_D(QQuickWidget);
1535 Q_QUICK_INPUT_PROFILE(QQuickProfiler::Mouse, QQuickProfiler::InputMousePress, e->button(),
1536 e->buttons());
1537
1538 QMouseEvent mappedEvent(e->type(), e->position(), e->position(), e->globalPosition(),
1539 e->button(), e->buttons(), e->modifiers(), e->source());
1540 QCoreApplication::sendEvent(d->offscreenWindow, &mappedEvent);
1541 e->setAccepted(mappedEvent.isAccepted());
1542}
1543
1546{
1547 Q_D(QQuickWidget);
1548 Q_QUICK_INPUT_PROFILE(QQuickProfiler::Mouse, QQuickProfiler::InputMouseRelease, e->button(),
1549 e->buttons());
1550
1551 QMouseEvent mappedEvent(e->type(), e->position(), e->position(), e->globalPosition(),
1552 e->button(), e->buttons(), e->modifiers(), e->source());
1553 QCoreApplication::sendEvent(d->offscreenWindow, &mappedEvent);
1554 e->setAccepted(mappedEvent.isAccepted());
1555}
1556
1557#if QT_CONFIG(wheelevent)
1559void QQuickWidget::wheelEvent(QWheelEvent *e)
1560{
1561 Q_D(QQuickWidget);
1562 Q_QUICK_INPUT_PROFILE(QQuickProfiler::Mouse, QQuickProfiler::InputMouseWheel,
1563 e->angleDelta().x(), e->angleDelta().y());
1564
1565 // Wheel events only have local and global positions, no need to map.
1566 QCoreApplication::sendEvent(d->offscreenWindow, e);
1567}
1568#endif
1569
1574{
1575 Q_D(QQuickWidget);
1576 d->offscreenWindow->focusInEvent(event);
1577}
1578
1583{
1584 Q_D(QQuickWidget);
1585 d->offscreenWindow->focusOutEvent(event);
1586}
1587
1589{
1590 // No more than one of these 3 can be set
1592 return Qt::WindowMinimized;
1594 return Qt::WindowMaximized;
1596 return Qt::WindowFullScreen;
1597
1598 // No state means "windowed" - we ignore Qt::WindowActive
1599 return Qt::WindowNoState;
1600}
1601
1603{
1604 auto item = qobject_cast<QQuickItem *>(object);
1605 if (!item)
1606 return;
1607
1608 // Remap all QRectF values.
1610 if (e->queries() & query) {
1611 auto value = e->value(query);
1612 if (value.canConvert<QRectF>())
1613 e->setValue(query, item->mapRectToScene(value.toRectF()));
1614 }
1615 }
1616 // Remap all QPointF values.
1617 if (e->queries() & Qt::ImCursorPosition) {
1618 auto value = e->value(Qt::ImCursorPosition);
1619 if (value.canConvert<QPointF>())
1620 e->setValue(Qt::ImCursorPosition, item->mapToScene(value.toPointF()));
1621 }
1622}
1623
1626{
1627 Q_D(QQuickWidget);
1628
1629 switch (e->type()) {
1630
1631 case QEvent::Leave:
1632 case QEvent::TouchBegin:
1633 case QEvent::TouchEnd:
1635 case QEvent::TouchCancel: {
1636 // Touch events only have local and global positions, no need to map.
1637 bool res = QCoreApplication::sendEvent(d->offscreenWindow, e);
1638 if (e->isAccepted() && e->type() == QEvent::TouchBegin) {
1639 // If the TouchBegin got accepted, then make sure all points that have
1640 // an exclusive grabber are also accepted so that the widget code for
1641 // delivering touch events make this widget an implicit grabber of those
1642 // points.
1643 QPointerEvent *pointerEvent = static_cast<QPointerEvent *>(e);
1644 auto deliveredPoints = pointerEvent->points();
1645 for (auto &point : deliveredPoints) {
1646 if (pointerEvent->exclusiveGrabber(point))
1647 point.setAccepted(true);
1648 }
1649 }
1650 return res;
1651 }
1652
1654 return QCoreApplication::sendEvent(d->offscreenWindow, e);
1655
1657 return QCoreApplication::sendEvent(d->offscreenWindow->focusObject(), e);
1659 {
1660 bool eventResult = QCoreApplication::sendEvent(d->offscreenWindow->focusObject(), e);
1661 // The result in focusObject are based on offscreenWindow. But
1662 // the inputMethodTransform won't get updated because the focus
1663 // is on QQuickWidget. We need to remap the value based on the
1664 // widget.
1665 remapInputMethodQueryEvent(d->offscreenWindow->focusObject(), static_cast<QInputMethodQueryEvent *>(e));
1666 return eventResult;
1667 }
1668
1670 d->invalidateRenderControl();
1671 d->deviceLost = true;
1672 d->rhi = nullptr;
1673 break;
1674
1676 d->handleWindowChange();
1677 break;
1678
1680 {
1681 QScreen *newScreen = screen();
1682 if (d->offscreenWindow)
1683 d->offscreenWindow->setScreen(newScreen);
1684 break;
1685 }
1687 if (d->useSoftwareRenderer || d->outputTexture) {
1688 // This will check the size taking the devicePixelRatio into account
1689 // and recreate if needed.
1690 createFramebufferObject();
1691 d->render(true);
1692 }
1693 if (d->offscreenWindow) {
1694 QEvent dprChangeEvent(QEvent::DevicePixelRatioChange);
1695 QGuiApplication::sendEvent(d->offscreenWindow, &dprChangeEvent);
1696 }
1697 break;
1698 case QEvent::Show:
1699 case QEvent::Move:
1700 d->updatePosition();
1701 break;
1702
1704 d->offscreenWindow->setWindowState(resolveWindowState(windowState()));
1705 break;
1706
1708 return QCoreApplication::sendEvent(d->offscreenWindow, e);
1709
1710 case QEvent::Enter: {
1711 QEnterEvent *enterEvent = static_cast<QEnterEvent *>(e);
1712 QEnterEvent mappedEvent(enterEvent->position(), enterEvent->scenePosition(),
1713 enterEvent->globalPosition());
1714 const bool ret = QCoreApplication::sendEvent(d->offscreenWindow, &mappedEvent);
1715 e->setAccepted(mappedEvent.isAccepted());
1716 return ret;
1717 }
1718 default:
1719 break;
1720 }
1721
1722 return QWidget::event(e);
1723}
1724
1725#if QT_CONFIG(quick_draganddrop)
1726
1728void QQuickWidget::dragEnterEvent(QDragEnterEvent *e)
1729{
1730 Q_D(QQuickWidget);
1731 // Don't reject drag events for the entire widget when one
1732 // item rejects the drag enter
1733 d->offscreenWindow->event(e);
1734 e->accept();
1735}
1736
1738void QQuickWidget::dragMoveEvent(QDragMoveEvent *e)
1739{
1740 Q_D(QQuickWidget);
1741 // Drag/drop events only have local pos, so no need to map,
1742 // but QQuickWindow::event() does not return true
1743 d->offscreenWindow->event(e);
1744}
1745
1747void QQuickWidget::dragLeaveEvent(QDragLeaveEvent *e)
1748{
1749 Q_D(QQuickWidget);
1750 d->offscreenWindow->event(e);
1751}
1752
1754void QQuickWidget::dropEvent(QDropEvent *e)
1755{
1756 Q_D(QQuickWidget);
1757 d->offscreenWindow->event(e);
1758}
1759
1760#endif // quick_draganddrop
1761
1762// TODO: try to separate the two cases of
1763// 1. render() unconditionally without sync
1764// 2. sync() and then render if necessary
1765void QQuickWidget::triggerUpdate()
1766{
1767 Q_D(QQuickWidget);
1768 d->updatePending = true;
1769 if (!d->eventPending) {
1770 // There's no sense in immediately kicking a render off now, as
1771 // there may be a number of triggerUpdate calls to come from a multitude
1772 // of different sources (network, touch/mouse/keyboard, timers,
1773 // animations, ...), and we want to batch them all into single frames as
1774 // much as possible for the sake of interactivity and responsiveness.
1775 //
1776 // To achieve this, we set a timer and only perform the rendering when
1777 // this is complete.
1778 const int exhaustDelay = 5;
1779 d->updateTimer.start(exhaustDelay, Qt::PreciseTimer, this);
1780 d->eventPending = true;
1781 }
1782}
1783
1796{
1797 Q_D(QQuickWidget);
1798 QSurfaceFormat currentFormat = d->offscreenWindow->format();
1799 QSurfaceFormat newFormat = format;
1800 newFormat.setDepthBufferSize(qMax(newFormat.depthBufferSize(), currentFormat.depthBufferSize()));
1801 newFormat.setStencilBufferSize(qMax(newFormat.stencilBufferSize(), currentFormat.stencilBufferSize()));
1802 newFormat.setAlphaBufferSize(qMax(newFormat.alphaBufferSize(), currentFormat.alphaBufferSize()));
1803
1804 // Do not include the sample count. Requesting a multisampled context is not necessary
1805 // since we render into an FBO, never to an actual surface. What's more, attempting to
1806 // create a pbuffer with a multisampled config crashes certain implementations. Just
1807 // avoid the entire hassle, the result is the same.
1808 d->requestedSamples = newFormat.samples();
1809 newFormat.setSamples(0);
1810
1811 d->offscreenWindow->setFormat(newFormat);
1812}
1813
1822{
1823 Q_D(const QQuickWidget);
1824 return d->offscreenWindow->format();
1825}
1826
1833{
1834 return const_cast<QQuickWidgetPrivate *>(d_func())->grabFramebuffer();
1835}
1836
1848{
1849 Q_D(QQuickWidget);
1850 d->offscreenWindow->setColor(color);
1851}
1852
1872{
1873 Q_D(const QQuickWidget);
1874 return d->offscreenWindow;
1875}
1876
1881{
1882 Q_D(QQuickWidget);
1883 if (d->useSoftwareRenderer) {
1884 QPainter painter(this);
1885 d->updateRegion = d->updateRegion.united(event->region());
1886 if (d->updateRegion.isNull()) {
1887 //Paint everything
1888 painter.drawImage(rect(), d->softwareImage);
1889 } else {
1892 //Paint only the updated areas
1893 QRegion targetRegion;
1894 d->updateRegion.swap(targetRegion);
1895 for (auto targetRect : targetRegion) {
1896 auto sourceRect = transform.mapRect(QRectF(targetRect));
1897 painter.drawImage(targetRect, d->softwareImage, sourceRect);
1898 }
1899 }
1900 }
1901}
1902
1903void QQuickWidget::propagateFocusObjectChanged(QObject *focusObject)
1904{
1905 Q_D(QQuickWidget);
1906 if (QApplication::focusObject() != this)
1907 return;
1909 emit window->focusObjectChanged(focusObject);
1910}
1911
1913
1914#include "moc_qquickwidget_p.cpp"
1915
1916#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.
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
Definition qbytearray.h:122
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
Definition qbytearray.h:106
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:164
\inmodule QtCore
Definition qcoreevent.h:45
@ 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
bool isAccepted() const
Definition qcoreevent.h:303
The QFocusEvent class contains event parameters for widget focus events.
Definition qevent.h:469
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:585
\inmodule QtGui
Definition qimage.h:37
QImage copy(const QRect &rect=QRect()) const
Returns a sub-area of the image as a new image.
bool isNull() const
Returns true if it is a null image, otherwise returns false.
Definition qimage.cpp:1197
@ Format_RGBA8888_Premultiplied
Definition qimage.h:60
@ Format_ARGB32_Premultiplied
Definition qimage.h:48
QImage mirrored(bool horizontally=false, bool vertically=true) const &
Definition qimage.h:218
The QInputMethodQueryEvent class provides an event sent by the input context to input objects.
Definition qevent.h:678
The QKeyEvent class describes a key event.
Definition qevent.h:423
int key() const
Returns the code of the key that was pressed or released.
Definition qevent.h:433
static bool isDebugBuild() noexcept Q_DECL_CONST_FUNCTION
Definition qlist.h:74
T & first()
Definition qlist.h:628
static StandardButton critical(QWidget *parent, const QString &title, const QString &text, StandardButtons buttons=Ok, StandardButton defaultButton=NoButton)
\inmodule QtCore
Definition qlogging.h:68
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:648
\inmodule QtCore
Definition qmetaobject.h:18
static QMetaMethod fromSignal(PointerToMemberFunction signal)
\inmodule QtGui
Definition qevent.h:195
\inmodule QtCore
Definition qobject.h:90
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2823
Q_WEAK_OVERLOAD void setObjectName(const QString &name)
Sets the object's name to name.
Definition qobject.h:114
qreal devicePixelRatio() const
The QPaintEvent class contains event parameters for paint events.
Definition qevent.h:485
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:214
\inmodule QtCore\reentrant
Definition qpoint.h:23
constexpr int x() const noexcept
Returns the x coordinate of this point.
Definition qpoint.h:127
constexpr int y() const noexcept
Returns the y coordinate of this point.
Definition qpoint.h:132
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:348
const QList< QEventPoint > & points() const
Returns a list of points in this pointer event.
Definition qevent.h:86
T * data() const
Definition qpointer.h:56
bool isNull() const
Returns true if the referenced object has been destroyed or if there is no referenced object; otherwi...
Definition qpointer.h:67
The QQmlComponent class encapsulates a QML component definition.
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:64
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:76
qreal height
This property holds the height of this item.
Definition qquickitem.h:77
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)
void init(QQmlEngine *e=0)
QPointer< QQuickItem > root
void ensureEngine() const
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.
\module QtQuickWidgets \title Qt Quick Widgets C++ Classes
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 the given 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:483
The QRegion class specifies a clip region for a painter.
Definition qregion.h:27
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:547
\inmodule QtGui
Definition qrhi.h:568
void setTexture(QRhiTexture *tex)
Sets the texture tex.
Definition qrhi.h:575
void setRenderBuffer(QRhiRenderBuffer *rb)
Sets the renderbuffer rb.
Definition qrhi.h:578
void setResolveTexture(QRhiTexture *tex)
Sets the resolve texture tex.
Definition qrhi.h:587
\inmodule QtGui
Definition qrhi.h:1614
\inmodule QtGui
Definition qrhi.h:765
\inmodule QtGui
Definition qrhi.h:1694
void readBackTexture(const QRhiReadbackDescription &rb, QRhiReadbackResult *result)
Enqueues a texture-to-host copy operation as described by rb.
Definition qrhi.cpp:8788
void setDepthStencilBuffer(QRhiRenderBuffer *renderBuffer)
Sets the renderBuffer for depth-stencil.
Definition qrhi.h:632
void setColorAttachments(std::initializer_list< QRhiColorAttachment > list)
Sets the list of color attachments.
Definition qrhi.h:619
@ RenderTarget
Definition qrhi.h:886
\inmodule QtGui
Definition qrhi.h:1767
FrameOpResult endOffscreenFrame(EndFrameFlags flags={})
Ends, submits, and waits for the offscreen frame.
Definition qrhi.cpp:10475
bool makeThreadLocalNativeContextCurrent()
With OpenGL this makes the OpenGL context current on the current thread.
Definition qrhi.cpp:9729
bool isYUpInFramebuffer() const
Definition qrhi.cpp:9601
Implementation backend() const
Definition qrhi.cpp:8289
FrameOpResult beginOffscreenFrame(QRhiCommandBuffer **cb, BeginFrameFlags flags={})
Starts a new offscreen frame.
Definition qrhi.cpp:10456
const char * backendName() const
Definition qrhi.cpp:8321
@ MultisampleRenderBuffer
Definition qrhi.h:1795
QRhiResourceUpdateBatch * nextResourceUpdateBatch()
Definition qrhi.cpp:8854
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)
\inmodule QtCore
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:577
\inmodule QtCore
Definition qsize.h:207
constexpr QSize toSize() const noexcept
Returns an integer based copy of this size.
Definition qsize.h:390
\inmodule QtCore
Definition qsize.h:25
constexpr int height() const noexcept
Returns the height.
Definition qsize.h:132
constexpr int width() const noexcept
Returns the width.
Definition qsize.h:129
constexpr void setWidth(int w) noexcept
Sets the width to the given width.
Definition qsize.h:135
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:123
constexpr void setHeight(int h) noexcept
Sets the height to the given height.
Definition qsize.h:138
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:126
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5710
The QSurfaceFormat class represents the format of a QSurface. \inmodule QtGui.
int samples() const
Returns the number of samples per pixel when multisampling is enabled, or -1 when multisampling is di...
void setDepthBufferSize(int size)
Set the minimum depth buffer size to size.
int alphaBufferSize() const
Get the size in bits of the alpha channel of the color buffer.
void setAlphaBufferSize(int size)
Set the desired size in bits of the alpha channel of the color buffer.
int stencilBufferSize() const
Returns the stencil buffer size in bits.
void setStencilBufferSize(int size)
Set the preferred stencil buffer size to size bits.
void setSamples(int numSamples)
Set the preferred number of samples per pixel when multisampling is enabled to numSamples.
int depthBufferSize() const
Returns the depth buffer size.
\inmodule QtCore
Definition qcoreevent.h:359
The QTransform class specifies 2D transformations of a coordinate system.
Definition qtransform.h:20
\inmodule QtCore
Definition qurl.h:94
static QWidgetPrivate * get(QWidget *w)
Definition qwidget_p.h:211
QWidgetRepaintManager * maybeRepaintManager() const
Definition qwidget_p.h:850
std::unique_ptr< QWExtra > extra
Definition qwidget_p.h:639
void setRenderToTexture()
Definition qwidget_p.h:604
virtual QPlatformTextureList::Flags textureListFlags()
Definition qwidget_p.h:593
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:4320
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:9761
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:2490
bool event(QEvent *event) override
This is the main event handler; it handles event event.
Definition qwidget.cpp:8912
Qt::WindowStates windowState() const
Returns the current window state.
Definition qwidget.cpp:2895
QScreen * screen() const
Returns the screen the widget is on.
Definition qwidget.cpp:2503
QWindow::Visibility visibility
Definition qwindow_p.h:113
\inmodule QtGui
Definition qwindow.h:63
void setWidth(int arg)
Definition qwindow.cpp:1627
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:972
void setHeight(int arg)
Definition qwindow.cpp:1637
#define this
Definition dialogs.cpp:9
void statusChanged(QDeclarativeComponent::Status status)
[1]
Definition qlogging.cpp:9
double e
short next
Definition keywords.cpp:445
Combined button and popup list for selecting options.
WindowState
Definition qnamespace.h:250
@ WindowFullScreen
Definition qnamespace.h:254
@ WindowNoState
Definition qnamespace.h:251
@ WindowMinimized
Definition qnamespace.h:252
@ WindowMaximized
Definition qnamespace.h:253
@ ImAnchorRectangle
@ ImInputItemClipRectangle
@ ImCursorPosition
@ ImCursorRectangle
@ WA_AcceptTouchEvents
Definition qnamespace.h:403
@ WA_Resized
Definition qnamespace.h:307
@ PreciseTimer
@ StrongFocus
Definition qnamespace.h:109
@ Key_Tab
Definition qnamespace.h:659
@ Key_Backtab
Definition qnamespace.h:660
@ NoModifier
@ AA_ShareOpenGLContexts
Definition qnamespace.h:446
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:287
#define qGuiApp
#define qWarning
Definition qlogging.h:162
#define qFatal
Definition qlogging.h:164
return ret
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
#define SLOT(a)
Definition qobjectdefs.h:51
#define SIGNAL(a)
Definition qobjectdefs.h:52
GLsizei samples
GLenum mode
GLfloat GLfloat GLfloat w
[0]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLint GLsizei width
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:483
#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:1391
QLatin1StringView QLatin1String
Definition qstringfwd.h:31
#define emit
unsigned char uchar
Definition qtypes.h:27
QWindow * qobject_cast< QWindow * >(QObject *o)
Definition qwindow.h:367
QUrl url("example.com")
[constructor-url-reference]
QObject::connect nullptr
myObject disconnect()
[26]
QGraphicsScene scene
[0]
QGraphicsItem * item
app setAttribute(Qt::AA_DontShowIconsInMenus)
QPainter painter(this)
[7]
QNetworkProxy proxy
[0]
QQuickView * view
[0]
QJSEngine engine
[0]
\inmodule QtGui
Definition qrhi.h:1686
QByteArray data
Definition qrhi.h:1690
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent