truf
truf

Reputation: 3111

Display QQmlComponent in QQuickWidget

According to QQuickWidget's documentation:

you can instantiate your own objects using QQmlComponent and place them in a manually set up QQuickWidget.

But I can't find any example of that. I would like to have multiple QQmlComponents loaded into RAM and display them in QQuickWidget depending on which one is active. Any idea on how to display any content in QQuickWidget except for setSource()?

Upvotes: 2

Views: 1054

Answers (1)

truf
truf

Reputation: 3111

I've end up with following solution: create new QQuickWidget widget and use its QQuickWidget::setContent() to display already created QML content in it. It works in my Qt 5.9.

Note: setContent() is marked as internal and have some drawbacks although this API is public and available in public header.

First of all, QQuickWidget doesn't clear its content when QQuickWidget::setContent() is consequently called for different data. So old and new content overlaps. That's why I have to create a new QQuickWidget on every content change and replace old QQuickWidget with new fresh one.

Secondly, QQuickWidget thinks it owns pointers passed via QQuickWidget::setContent() and tries to delete content at destruction. To bypass this you may execute QQuickWidget::setContent(QUrl(), nullptr, nullptr) before QQuickWidget instance is destroyed. But this triggers a warning message from QML engine in stdout about incorrect qml content. So better approach is to set dummy data:

QQmlComponent* dummy = new QQmlComponent(engine);
dummy->setData(QByteArray("import QtQuick 2.0; Item { }"), QUrl());
wgt->setContent(dummy->url(), dummy, dummy->create());
wgt->deleteLater();

With these hacks I was able to load multiple QML objects (plugins with own UI) with QQmlComponent at runtime. Instantiate them and display one of them in QWidgets-based application depending on plugin selected.

Upvotes: 1

Related Questions