如何在运行时从C++创建QQmlComponent?

pep*_*epe 8 c++ qt object qml

我需要在运行时从C++代码添加QML组件.我可以从'main.qml'文件创建ApplicationWindow.窗口成功显示.问题是我无法将其他QML组件添加到此窗口.我在'button.qml'文件中指定了按钮.所以我尝试创建另一个QQmlComponent并将ApplicationWindow设置为按钮的父级.obj1-> children()的输出显示类型按钮的子节点存在(QQuickItem(0xcc08c0),Button_QMLTYPE_12(0xa7e6d0)).但是没有显示按钮.当我尝试将Button staticaly添加到'main.qml'时,一切正常.我在运行时创建QQmlComponent时遗漏了一些东西.

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);
Run Code Online (Sandbox Code Playgroud)

Sim*_*rta 20

请参阅从C++加载QML对象:

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());
Run Code Online (Sandbox Code Playgroud)

现在您创建了一个自定义Button组件的实例.

为了避免Javascript垃圾收集器杀死它,告诉QML C++负责它:

QQmlEngine::setObjectOwnership(object, QQmlEngine::CppOwnership);
Run Code Online (Sandbox Code Playgroud)

您需要2个父项:显示对象的可视父项和QObject父项,以确保object在删除时正确view删除.

object->setParentItem(root);
object->setParent(&view);
Run Code Online (Sandbox Code Playgroud)

随意object在QML中设置任何属性.为了确保,QML知道更改,请使用以下函数:

object->setProperty("color", QVariant(QColor(255, 255, 255)));
object->setProperty("text", QVariant(QString("foo")));
Run Code Online (Sandbox Code Playgroud)

完成.

替代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")));
Run Code Online (Sandbox Code Playgroud)