如何从C++创建具备正确组件作用域实例层级的QML组件
问题原因
你动态创建的QML组件没有继承到TestMain.qml中对应父节点的QML上下文,QML的属性查找依赖上下文链,默认从C++调用QQmlComponent::createWithInitialProperties时如果不传上下文参数,组件会绑定到引擎根上下文,自然找不到上层ApplicationWindow里定义的x_SCALE、y_SCALE属性。
另外你当前通过children()[1]硬编码索引获取wrapper的方式非常不稳定,QML对象树的children顺序会随内部结构变化变动,很容易取到错误的对象,也可能导致属性访问异常。
解决方案
方案1:创建组件时指定正确上下文(推荐)
创建组件时传入wrapper的创建上下文,让动态生成的组件上下文链和直接在QML中声明在wrapper内部的组件完全一致:
首先修改TestMain.qml给wrapper加objectName避免硬编码索引:
Item { id: wrapper objectName: "wrapper" // 新增这行 anchors.fill: parent }
再修改C++代码:
engine->load("TestMain.qml"); if (engine->rootObjects().isEmpty()) { // 错误处理逻辑 } auto root = engine->rootObjects().first(); // 改用findChild查找wrapper,稳定可靠 auto wrapper = root->findChild<QQuickItem*>("wrapper"); if (!wrapper) { // 找不到wrapper的错误处理逻辑 } QQmlComponent component(engine.get(), "ComponentToBeTested.qml"); // 创建时传入wrapper的上下文作为第二个参数 auto item = qobject_cast<QQuickItem*>(component.createWithInitialProperties(props, wrapper->creationContext())); if (!item) { // 组件创建失败的错误处理,可通过component.errorString()打印错误信息 } item->setParentItem(wrapper); item->setSize(wrapper->size()); app->exec();
方案2:手动传递属性
如果不需要访问更多上层属性,也可以直接把需要的属性手动加入初始化参数中:
// 从root对象取出两个缩放属性的值加入props props.insert("x_SCALE", root->property("x_SCALE").toReal()); props.insert("y_SCALE", root->property("y_SCALE").toReal()); // 再正常创建组件即可 auto item = qobject_cast<QQuickItem*>(component.createWithInitialProperties(props));
内容的提问来源于stack exchange,提问作者pooya13
相关产品推荐
相关产品推荐

