Lazy create QmlEngine on accessing rootContext

A common usecase appears to be to set variables in the rootContext
before loading a url in a QQuickWidget. We there need to ensure there
is a QmlEngine to set variables on when this is attempted.

Change-Id: I07aff2104313eeb3fab902ea3c6043c3c82c50f7
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
This commit is contained in:
Allan Sandfeld Jensen 2016-06-27 11:55:33 +02:00 committed by Allan Sandfeld Jensen
parent c9d4c8ed97
commit 97212616d5
3 changed files with 14 additions and 8 deletions

View File

@ -109,13 +109,13 @@ void QQuickWidgetPrivate::init(QQmlEngine* e)
QObject::connect(renderControl, SIGNAL(sceneChanged()), q, SLOT(triggerUpdate())); QObject::connect(renderControl, SIGNAL(sceneChanged()), q, SLOT(triggerUpdate()));
} }
void QQuickWidgetPrivate::ensureEngine() void QQuickWidgetPrivate::ensureEngine() const
{ {
Q_Q(QQuickWidget); Q_Q(const QQuickWidget);
if (!engine.isNull()) if (!engine.isNull())
return; return;
engine = new QQmlEngine(q); engine = new QQmlEngine(const_cast<QQuickWidget*>(q));
engine.data()->setIncubationController(offscreenWindow->incubationController()); engine.data()->setIncubationController(offscreenWindow->incubationController());
} }
@ -493,7 +493,8 @@ QUrl QQuickWidget::source() const
QQmlEngine* QQuickWidget::engine() const QQmlEngine* QQuickWidget::engine() const
{ {
Q_D(const QQuickWidget); Q_D(const QQuickWidget);
return d->engine ? const_cast<QQmlEngine *>(d->engine.data()) : 0; d->ensureEngine();
return const_cast<QQmlEngine *>(d->engine.data());
} }
/*! /*!
@ -506,7 +507,8 @@ QQmlEngine* QQuickWidget::engine() const
QQmlContext* QQuickWidget::rootContext() const QQmlContext* QQuickWidget::rootContext() const
{ {
Q_D(const QQuickWidget); Q_D(const QQuickWidget);
return d->engine ? d->engine.data()->rootContext() : 0; d->ensureEngine();
return d->engine.data()->rootContext();
} }
/*! /*!

View File

@ -105,7 +105,7 @@ public:
QImage grabFramebuffer() Q_DECL_OVERRIDE; QImage grabFramebuffer() Q_DECL_OVERRIDE;
void init(QQmlEngine* e = 0); void init(QQmlEngine* e = 0);
void ensureEngine(); void ensureEngine() const;
void handleWindowChange(); void handleWindowChange();
void invalidateRenderControl(); void invalidateRenderControl();
@ -115,7 +115,7 @@ public:
QUrl source; QUrl source;
QPointer<QQmlEngine> engine; mutable QPointer<QQmlEngine> engine;
QQmlComponent *component; QQmlComponent *component;
QBasicTimer resizetimer; QBasicTimer resizetimer;
QQuickWindow *offscreenWindow; QQuickWindow *offscreenWindow;

View File

@ -305,9 +305,13 @@ void tst_qquickwidget::grabBeforeShow()
void tst_qquickwidget::nullEngine() void tst_qquickwidget::nullEngine()
{ {
QQuickWidget widget; QQuickWidget widget;
QVERIFY(widget.engine() == Q_NULLPTR); // Default should have no errors, even with a null qml engine
QVERIFY(widget.errors().isEmpty()); QVERIFY(widget.errors().isEmpty());
QCOMPARE(widget.status(), QQuickWidget::Null); QCOMPARE(widget.status(), QQuickWidget::Null);
// A QML engine should be created lazily.
QVERIFY(widget.rootContext());
QVERIFY(widget.engine());
} }
QTEST_MAIN(tst_qquickwidget) QTEST_MAIN(tst_qquickwidget)