0

Normally we set up a Qt application in this way:

QGuiApplication qtapp(argc, argv);
QQuickView rootView;
rootView.setResizeMode(QQuickView::SizeRootObjectToView);
rootView.setSource(QUrl("qrc:myfile.qml"));
rootView.show();

QQmlEngine * qmlEngine = view.engine();
QQmlComponent component(qmlEngine, QUrl("qrc:myview.qml"));
QQuickItem *  qItem = qobject_cast<QQuickItem *>(component.create());

However, we would like to get rid of the external qml files and pass the source code directly. This is possible for the QQuickItem in this way:

QQmlEngine * qmlEngine = view.engine();
QQmlComponent component(qmlEngine);
component.setData("my source code here", QUrl());
QQuickItem *  qItem = qobject_cast<QQuickItem *>(component.create());

However, we have not been able to do the same for the rootView. How can we do that?

kalj
  • 1,432
  • 2
  • 13
  • 30
  • You know you can embed the QML files in your application as resources and then load the embedded resource, right? – Jesper Juhl Apr 27 '23 at 12:44
  • You can construct `QUrl`s for local file paths, so dump your string to a temporary file and reference that? – Botje Apr 27 '23 at 12:48
  • 1
    Another interesting solution would be to use a QNetworkAccessManager, the name suggest the data should come from the network, but you can implement it however you like – Amfasis Apr 28 '23 at 06:07
  • @Amfasis I tried that previously, as suggested here: https://stackoverflow.com/questions/41733670/dynamically-loading-qml-from-memory-instead-of-a-url, but it was way more complicated. I might go back to that approach if nothing easier turns up. – kalj Apr 28 '23 at 11:41
  • yes, it depends a bit on the situation. Could you clarify where the sources should come from? – Amfasis Apr 28 '23 at 12:23
  • Errr... who is *we*? – karlphillip Apr 28 '23 at 22:47

2 Answers2

1

It seems like QQuickView doesn't have this functionality, but QQmlComponent has it and as the documentation about QQuickView states

This is a convenience subclass of QQuickWindow which will automatically load and display a QML scene when given the URL of the main source file. Alternatively, you can instantiate your own objects using QQmlComponent and place them in a manually setup QQuickWindow.

So it might be possible by using QQmlComponent in combination with QQuickWindow instead of the QQuickView. Something like this of course with your way of setting the QML source in between:

QQmlEngine engine;
QQmlComponent component(&engine);
QObject* obj = component.create();
QQuickWindow* win = qobject_cast<QQuickWindow*>(obj);

I got the source from this gist when I searched for QQuickWindow used with QQmlComponent.

iam_peter
  • 3,205
  • 1
  • 19
  • 31
0

Your question title indicates how to load QML from string, whereas your question body says how to load QML from URL. Let's answer both:

Answer 1: Loading QML from C++ string

QQmlApplicationEngine engine;
engine.rootContext().setContextProperty("sourcecode","source code");

Then, have a mini QML source code compiler in your app like this:

Page {
    id: page
    anchors.fill: parent
    property var obj: null
    function compile(code, filePath) {
        if (obj) { obj.destroy(); obj = null; }
        if (!code) { return; }
        obj = Qt.createQmlObject(code, page, filePath ?? "dynamic");
        obj.width = Qt.binding( () => page.width );
        obj.height = Qt.binding( () => page.height );
    }
    Component.onCompleted: compile(sourcecode)
}

Answer 2: Load QML from C++ URL

This is similar to the above:

QQmlApplicationEngine engine;
engine.rootContext().setContextProperty("sourceurl","source code url");

Then in QML have a loader, e.g.

Page {
    id: page
    Loader {
        anchors.fill: parent
        source: sourceurl
    }
}
Stephen Quan
  • 21,481
  • 4
  • 88
  • 75