How to create a QQmlComponent from C ++ at runtime?

I need to add QML components at runtime from C ++ code. I can create ApplicationWindow from the file 'main.qml'. The window is displayed successfully. The problem is that I cannot add other QML components to this window. I have a button specified in the button.qml file. So I tried to create another QQmlComponent and set the parent element for ApplicationWindow. The output of obj1-> children () shows that there are buttons of type children (QQuickItem (0xcc08c0), Button_QMLTYPE_12 (0xa7e6d0)). But the button is not displayed. When I try to add Button staticaly to 'main.qml', everything works fine. I am missing something in creating a QQmlComponent at runtime.

QQmlEngine engine;

QQmlComponent component1(&engine, QUrl("qrc:/main.qml"));
QQmlComponent component2(&engine, QUrl("qrc:/button.qml"));

QObject* obj1 = component1.create();
QObject* obj2 = component2.create();

obj2->setParent(obj1);
+4
source share
1 answer

See Loading QML objects from C ++ :

QQuickView view;
view.setSource(QUrl("qrc:/main.qml"));
view.show();
QQuickItem *root = view.rootObject()

QQmlComponent component(view.engine(), QUrl("qrc:/Button.qml"));
QQuickItem *object = qobject_cast<QQuickItem*>(component.create());

You have now created an instance of the custom component Button.

To avoid javascript garbage collection in order to kill it, tell QML that C ++ will take care of this:

QQmlEngine::setObjectOwnership(object, QQmlEngine::CppOwnership);

You need 2 parents: a visual parent to show the object and a QObject parent to objectbe deleted correctly when viewdeleted.

object->setParentItem(root);
object->setParent(&view);

It is not possible to set any property in object, as in QML. To make sure QML is aware of the change, use the following function:

object->setProperty("color", QVariant(QColor(255, 255, 255)));
object->setProperty("text", QVariant(QString("foo")));

Done.

Alternative version of QQmlEngine :

QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
QQuickWindow *window = qobject_cast<QQuickWindow*>(engine.rootObjects().at(0));
if (!window) {
    qFatal("Error: Your root item has to be a window.");
    return -1;
}
window->show();
QQuickItem *root = window->contentItem();

QQmlComponent component(&engine, QUrl("qrc:/Button.qml"));
QQuickItem *object = qobject_cast<QQuickItem*>(component.create());

QQmlEngine::setObjectOwnership(object, QQmlEngine::CppOwnership);

object->setParentItem(root);
object->setParent(&engine);

object->setProperty("color", QVariant(QColor(255, 255, 255)));
object->setProperty("text", QVariant(QString("foo")));
+16
source

All Articles