7#include <QtWidgets/private/qwidgetrepaintmanager_p.h>
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"
15#include "private/qsgsoftwarerenderer_p.h"
17#include <private/qqmldebugconnector_p.h>
18#include <private/qquickprofiler_p.h>
19#include <private/qqmldebugserviceinterfaces_p.h>
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>
28#include <QtGui/QPainter>
30#include <QtQuick/QSGRendererInterface>
33#if QT_CONFIG(messagebox)
34# include <QtWidgets/QMessageBox>
36# include <QtCore/QLibraryInfo>
37# include <QtCore/qt_windows.h>
40#include <QtQuick/qquickgraphicsdevice.h>
41#include <QtQuick/qquickrendertarget.h>
43#include "private/qwidget_p.h"
45#if QT_CONFIG(graphicsview)
46#include <QtWidgets/qgraphicsscene.h>
47#include <QtWidgets/qgraphicsview.h>
51#include <QtGui/private/qvulkandefaultinstance_p.h>
97#if QT_CONFIG(graphicsview)
99 auto *
proxy = (widgetd && widgetd->extra) ? widgetd->extra->proxyWidget :
nullptr;
103 if (
view->window()->windowHandle() ==
w)
123 *
offset =
d->m_quickWidget->mapTo(
d->m_quickWidget->window(),
QPoint());
126#if QT_CONFIG(graphicsview)
128 if (widgetd->extra) {
129 if (
auto proxy = widgetd->extra->proxyWidget) {
133 if (!views.isEmpty()) {
136 auto candidateView = views.
first();
137 result = candidateView->window()->windowHandle();
144 result =
d->m_quickWidget->window()->windowHandle();
161#if QT_CONFIG(accessibility)
162 QAccessible::installFactory(&qAccessibleQuickWidgetFactory);
195 qWarning(
"QQuickWidget is not supported on this platform.");
203 q->setMouseTracking(
true);
224#if QT_CONFIG(quick_draganddrop)
225 q->setAcceptDrops(
true);
298 , eventPending(
false)
299 , updatePending(
false)
301 , requestedSamples(0)
302 , useSoftwareRenderer(
false)
303 , forceFullUpdate(
false)
312 q->destroyFramebufferObject();
334 q->continueExecute();
337 q,
SLOT(continueExecute()));
343 const QRectF &oldGeometry)
360 q->createFramebufferObject();
364 qWarning(
"QQuickWidget: Attempted to render scene with no rhi");
383 qWarning(
"QQuickWidget: Failed to begin recording a frame");
408 softwareRenderer->markDirty();
428#if QT_CONFIG(graphicsview)
429 if (
q->window()->graphicsProxyWidget())
430 QWidgetPrivate::nearestGraphicsProxyWidget(
q)->update();
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(),
464 return wrapperImage.mirrored();
466 return wrapperImage.copy();
678 d->rhi->removeCleanupCallback(
this);
726 if (
d->component &&
d->component->isError()) {
727 const QList<QQmlError> errorList =
d->component->errors();
736 d->setRootObject(
item);
773 return d->engine.data()->rootContext();
818 if (!
d->engine && !
d->source.isEmpty())
839 QList<QQmlError> errs;
842 errs =
d->component->errors();
844 if (!
d->engine && !
d->source.isEmpty()) {
878 if (
d->resizeMode ==
mode)
888 d->resizeMode =
mode;
914 if (newSize !=
q->size()) {
927 if (needToUpdateWidth && needToUpdateHeight) {
932 const QSizeF newSize(
q->width(),
q->height());
936 }
else if (needToUpdateWidth) {
937 const int newWidth =
q->width();
941 }
else if (needToUpdateHeight) {
942 const int newHeight =
q->height();
969 int widthCandidate = -1;
970 int heightCandidate = -1;
975 if (widthCandidate > 0) {
978 if (heightCandidate > 0) {
993 const bool signalConnected =
q->isSignalConnected(errorSignal);
995 emit q->sceneGraphError(QQuickWindow::ContextNotAvailable, translatedMessage);
997#if defined(Q_OS_WIN) && QT_CONFIG(messagebox)
1001 if (!signalConnected)
1031 if (backingStoreRhi &&
rhi != backingStoreRhi)
1039 if (!onlyNeedsSgInit) {
1044 rhi = backingStoreRhi;
1047 if (this->rhi ==
rhi) {
1050 this->rhi =
nullptr;
1071 qWarning(
"The top-level window is not using the expected graphics API for composition, "
1072 "'%s' is not compatible with this QQuickWidget",
1081#if QT_CONFIG(vulkan)
1082 if (
QWindow *
w =
q->window()->windowHandle())
1085 offscreenWindow->setVulkanInstance(QVulkanDefaultInstance::instance());
1090 qWarning(
"QQuickWidget: Failed to get a QRhi from the top-level widget's window");
1094void QQuickWidget::createFramebufferObject()
1100 if (
size().isEmpty())
1107 d->offscreenWindow->setGeometry(globalPos.
x(), globalPos.
y(),
width(),
height());
1109 if (
d->useSoftwareRenderer) {
1113 d->forceFullUpdate =
true;
1118 qWarning(
"QQuickWidget: Attempted to create output texture with no QRhi");
1131 if (!
d->outputTexture) {
1133 if (!
d->outputTexture->create()) {
1134 qWarning(
"QQuickWidget: failed to create output texture of size %dx%d",
1135 fboSize.width(), fboSize.height());
1138 if (!
d->depthStencil) {
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);
1145 if (
samples > 1 && !
d->msaaBuffer) {
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);
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);
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());
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());
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());
1190 d->renderControl->setSamples(
samples);
1195 Q_ASSERT(!
d->offscreenWindow->handle());
1198void QQuickWidget::destroyFramebufferObject()
1202 if (
d->useSoftwareRenderer) {
1211 delete d->depthStencil;
1212 d->depthStencil =
nullptr;
1213 delete d->msaaBuffer;
1214 d->msaaBuffer =
nullptr;
1215 delete d->outputTexture;
1216 d->outputTexture =
nullptr;
1222 return d->resizeMode;
1228void QQuickWidget::continueExecute()
1233 if (
d->component->isError()) {
1234 const QList<QQmlError> errorList =
d->component->errors();
1245 if (
d->component->isError()) {
1246 const QList<QQmlError> errorList =
d->component->errors();
1255 d->setRootObject(
obj);
1271 }
else if (qobject_cast<QWindow *>(
obj)) {
1272 qWarning() <<
"QQuickWidget does not support using windows as a root item." <<
Qt::endl
1274 <<
"If you wish to create your root window from QML, consider using QQmlApplicationEngine instead." <<
Qt::endl;
1276 qWarning() <<
"QQuickWidget only supports loading of root objects that derive from QQuickItem." <<
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;
1310 config.setDebugLayer(debugLayerRequested);
1317 if (!
q->isWindow() &&
q->internalWinId()) {
1318 qWarning() <<
"QQuickWidget cannot be used as a native child widget."
1319 <<
"Consider setting Qt::AA_DontCreateNativeWidgetSiblings";
1339 if (!e || e->
timerId() ==
d->resizetimer.timerId()) {
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();
1357 QSize rootObjectSize =
d->rootObjectSize();
1358 if (rootObjectSize.
isEmpty()) {
1361 return rootObjectSize;
1375 return d->initialSize;
1402 d->fakeHidden =
true;
1406 bool needsSync =
false;
1407 if (
d->fakeHidden) {
1409 d->fakeHidden =
false;
1414 if (
d->useSoftwareRenderer) {
1417 createFramebufferObject();
1423 if (!
d->outputTexture && !
d->offscreenWindow->isSceneGraphInitialized())
1427 createFramebufferObject();
1433 d->initializeWithRhi();
1437 qWarning(
"QQuickWidget::resizeEvent() no QRhi");
1442 d->render(needsSync);
1458 return event.isAccepted();
1495 mappedEvent.setTimestamp(e->
timestamp());
1511 pressEvent.setTimestamp(e->
timestamp());
1516 mappedEvent.setTimestamp(e->
timestamp());
1524 bool shouldTriggerUpdate =
true;
1526 if (!
d->useSoftwareRenderer) {
1527 d->initializeWithRhi();
1529 if (
d->offscreenWindow->isSceneGraphInitialized()) {
1530 shouldTriggerUpdate =
false;
1539 if (!
d->eventPending &&
d->updatePending) {
1540 d->updatePending =
false;
1546 if (shouldTriggerUpdate)
1550 d->offscreenWindow->setVisible(
true);
1559 if (!
d->offscreenWindow->isPersistentSceneGraph())
1560 d->invalidateRenderControl();
1562 d->offscreenWindow->setVisible(
false);
1564 service->setParentWindow(
d->offscreenWindow,
d->offscreenWindow);
1576 mappedEvent.setTimestamp(e->
timestamp());
1590 mappedEvent.setTimestamp(e->
timestamp());
1595#if QT_CONFIG(wheelevent)
1597void QQuickWidget::wheelEvent(QWheelEvent *e)
1601 e->angleDelta().x(), e->angleDelta().y());
1614 d->offscreenWindow->focusInEvent(
event);
1623 d->offscreenWindow->focusOutEvent(
event);
1667 switch (e->
type()) {
1682 auto deliveredPoints = pointerEvent->
points();
1683 for (
auto &point : deliveredPoints) {
1685 point.setAccepted(
true);
1709 d->rhi->removeCleanupCallback(
this);
1710 d->invalidateRenderControl();
1711 d->deviceLost =
true;
1716 d->handleWindowChange();
1722 if (
d->offscreenWindow)
1723 d->offscreenWindow->setScreen(newScreen);
1727 if (
d->useSoftwareRenderer ||
d->outputTexture) {
1730 createFramebufferObject();
1733 if (
d->offscreenWindow) {
1740 d->updatePosition();
1765#if QT_CONFIG(quick_draganddrop)
1768void QQuickWidget::dragEnterEvent(QDragEnterEvent *e)
1773 d->offscreenWindow->event(e);
1778void QQuickWidget::dragMoveEvent(QDragMoveEvent *e)
1783 d->offscreenWindow->event(e);
1787void QQuickWidget::dragLeaveEvent(QDragLeaveEvent *e)
1790 d->offscreenWindow->event(e);
1794void QQuickWidget::dropEvent(QDropEvent *e)
1797 d->offscreenWindow->event(e);
1805void QQuickWidget::triggerUpdate()
1808 d->updatePending =
true;
1809 if (!
d->eventPending) {
1818 const int exhaustDelay = 5;
1820 d->eventPending =
true;
1841 newFormat.setStencilBufferSize(
qMax(newFormat.stencilBufferSize(), currentFormat.stencilBufferSize()));
1842 newFormat.setAlphaBufferSize(
qMax(newFormat.alphaBufferSize(), currentFormat.alphaBufferSize()));
1848 d->requestedSamples = newFormat.samples();
1849 newFormat.setSamples(0);
1851 d->offscreenWindow->setFormat(newFormat);
1864 return d->offscreenWindow->format();
1890 d->offscreenWindow->setColor(
color);
1914 return d->offscreenWindow;
1923 if (
d->useSoftwareRenderer) {
1925 d->updateRegion =
d->updateRegion.united(
event->region());
1926 if (
d->updateRegion.isNull()) {
1934 d->updateRegion.
swap(targetRegion);
1935 for (
auto targetRect : targetRegion) {
1943void QQuickWidget::propagateFocusObjectChanged(
QObject *focusObject)
1949 emit window->focusObjectChanged(focusObject);
1954#include "moc_qquickwidget_p.cpp"
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.
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
virtual void setAccepted(bool accepted)
@ WindowAboutToChangeInternal
Type type() const
Returns the event type.
The QFocusEvent class contains event parameters for widget focus events.
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.
bool isNull() const
Returns true if it is a null image, otherwise returns false.
@ Format_RGBA8888_Premultiplied
@ Format_ARGB32_Premultiplied
The QKeyEvent class describes a key event.
Qt::KeyboardModifiers modifiers() const
Returns the keyboard modifier flags that existed immediately after the event occurred.
int key() const
Returns the code of the key that was pressed or released.
static bool isDebugBuild() noexcept Q_DECL_CONST_FUNCTION
bool isEmpty() const noexcept
static StandardButton critical(QWidget *parent, const QString &title, const QString &text, StandardButtons buttons=Ok, StandardButton defaultButton=NoButton)
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.
Qt::MouseEventSource source() const
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Q_WEAK_OVERLOAD void setObjectName(const QString &name)
Sets the object's name to name.
qreal devicePixelRatio() const
The QPaintEvent class contains event parameters for paint events.
The QPainter class performs low-level painting on widgets and other paint devices.
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...
@ NeedsPremultipliedAlphaBlending
\inmodule QtCore\reentrant
constexpr qreal x() const noexcept
Returns the x coordinate of this point.
constexpr qreal y() const noexcept
Returns the y coordinate of this point.
\inmodule QtCore\reentrant
constexpr int x() const noexcept
Returns the x coordinate of this point.
constexpr int y() const noexcept
Returns the y coordinate of this point.
A base class for pointer events.
QObject * exclusiveGrabber(const QEventPoint &point) const
Returns the object which has been set to receive all future update events and the release event conta...
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...
virtual void setAccepted(bool accepted) override
\reimp
const QList< QEventPoint > & points() const
Returns a list of points in this pointer event.
T * data() const noexcept
bool isNull() const noexcept
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.
The QQmlEngine class provides an environment for instantiating QML components.
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.
bool isDebugLayerEnabled() const
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}.
void setSize(const QSizeF &size)
void setParentItem(QQuickItem *parent)
qreal width
This property holds the width of this item.
qreal height
This property holds the height of this item.
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)
QQuickGraphicsConfiguration graphicsConfig
static QQuickWindowPrivate * get(QQuickWindow *c)
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
The QRegion class specifies a clip region for a painter.
void swap(QRegion &other) noexcept
bool isEmpty() const
Returns true if the region is empty; otherwise returns false.
The QResizeEvent class contains event parameters for resize events.
const QSize & size() const
Returns the new size of the widget.
void setTexture(QRhiTexture *tex)
Sets the texture tex.
void setRenderBuffer(QRhiRenderBuffer *rb)
Sets the renderbuffer rb.
void setResolveTexture(QRhiTexture *tex)
Sets the resolve texture tex.
\inmodule QtGuiPrivate \inheaderfile rhi/qrhi.h
FrameOpResult endOffscreenFrame(EndFrameFlags flags={})
Ends, submits, and waits for the offscreen frame.
bool makeThreadLocalNativeContextCurrent()
With OpenGL this makes the OpenGL context current on the current thread.
bool isYUpInFramebuffer() const
Implementation backend() const
FrameOpResult beginOffscreenFrame(QRhiCommandBuffer **cb, BeginFrameFlags flags={})
Starts a new offscreen frame.
const char * backendName() const
void addCleanupCallback(const CleanupCallback &callback)
Registers a callback that is invoked either when the QRhi is destroyed, or when runCleanup() is calle...
@ MultisampleRenderBuffer
QRhiResourceUpdateBatch * nextResourceUpdateBatch()
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.
The QShowEvent class provides an event that is sent when a widget is shown.
QPointF globalPosition() const
Returns the position of the point in this event on the screen or virtual desktop.
QPointF position() const
Returns the position of the point in this event, relative to the widget or item that received the eve...
Qt::MouseButton button() const
Returns the button that caused the event.
Qt::MouseButtons buttons() const
Returns the button state when the event was generated.
constexpr QSize toSize() const noexcept
Returns an integer based copy of this size.
constexpr void setWidth(int w) noexcept
Sets the width to the given width.
constexpr bool isEmpty() const noexcept
Returns true if either of the width and height is less than or equal to 0; otherwise returns false.
constexpr void setHeight(int h) noexcept
Sets the height to the given height.
constexpr bool isValid() const noexcept
Returns true if both the width and height is equal to or greater than 0; otherwise returns false.
\macro QT_RESTRICTED_CAST_FROM_ASCII
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
int timerId() const
Returns the unique timer identifier, which is the same identifier as returned from QObject::startTime...
QWindow::Visibility visibility
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 &)
void statusChanged(QQmlComponent::Status status)
[1]
Combined button and popup list for selecting options.
@ ImInputItemClipRectangle
QTextStream & endl(QTextStream &stream)
Writes '\n' to the stream and flushes the stream.
DBusConnection const char DBusError * error
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
constexpr const T & qMax(const T &a, const T &b)
GLfloat GLfloat GLfloat w
[0]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLuint GLintptr offset
GLint GLsizei GLsizei GLenum format
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei imageSize
GLsizei GLsizei GLchar * source
GLuint GLenum GLenum transform
GLdouble GLdouble GLdouble GLdouble q
static qreal component(const QPointF &point, unsigned int i)
QQuickItem * qobject_cast< QQuickItem * >(QObject *o)
#define Q_QUICK_INPUT_PROFILE(Type, DetailType, A, B)
SSL_CTX int(* cb)(SSL *ssl, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
#define qPrintable(string)
QLatin1StringView QLatin1String
QUrl url("example.com")
[constructor-url-reference]
myObject disconnect()
[26]
QNetworkRequestFactory api
[0]