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

14

我需要在C++代码中动态添加QML组件。我能够从'main.qml'文件创建ApplicationWindow并成功显示窗口。问题在于我无法向此窗口添加其他QML组件。我在'button.qml'文件中指定了一个按钮。因此,我尝试创建另一个QQmlComponent并将ApplicationWindow设置为该按钮的父级。 obj1->children()的输出显示存在类型为button的子项(QQuickItem(0xcc08c0),Button_QMLTYPE_12(0xa7e6d0))。但是按钮没有显示出来。当我尝试静态地将按钮添加到'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);
1个回答

29

请参考从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());

现在您已经创建了一个自定义组件的实例。

为避免Javascript垃圾收集器将其删除,请告诉QML由C++负责:

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

你需要2个父级:一个可视父级来显示对象和一个QObject父级, 以确保在删除view时正确地删除object

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

可以像在QML中一样自由地设置object的任何属性。为了确保QML知道这些更改,请使用以下函数:

随意设置object的任何属性,就像在QML中一样。要确保QML知道这些更改,请使用以下函数:

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

已完成。

替代的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")));

1
备选的 QQmlEngine 版本运行良好。QQuickView 将在旧的 QtQuick 版本中工作。我使用 QtQuick 2.3。 - pepe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接