QML:修改在另一个QML文件(不是main.qml)中定义的Child对象的属性

时间:2018-10-30 12:08:49

标签: c++ qt qml

基本上,我有类似的东西:

Main.qml:

ApplicationWindow{
width: 500
height: 500

    Page{
    id: page0

        DataPage{
          id: datapage0  
        }
    }
}

DataPage.qml:

Page{
id: displayPage

    DataDisplay{
    id: dataShow
    }
}

DataDisplay.qml:

Label{
text: "data: "
}

TextArea{
id: dataArea
text: ""
}

我删除了我认为不相关的内容(例如锚点,高度,宽度等)。现在,在main.qml中,我有一个来自c ++后端的信号:

Connections{
target: modb
onPostData: {
    page0.datapage0.dataShow.dataArea.text = string;
}

然后出现以下错误:     TypeError:无法读取未定义的属性'dataArea'

因此,我想问:如何将信号连接到DataDisplay.qml中定义的子对象?我可以使用信号将信息输入到main.qml中,但似乎无法取消引用子对象

编辑:

main.cpp:

QQmlContext* ctx0 = engine.rootContext();
ctx0->setContextProperty("ark", &ark);

QQmlContext* ctx1 = engine.rootContext();
ctx1->setContextProperty("comm", ark.comm);

QQmlContext* ctx2 = engine.rootContext();
ctx2->setContextProperty("modb", ark.modb);

是我如何设置上下文(如您所见,共3个类)。我可以从这三个中的任何一个获取信号到main.qml中,也可以在这三个中的任何一个中获取呼叫槽;我还没有尝试从其他qml文件中的c ++类调用插槽,但是我认为它会起作用,因为我可以从子级访问父级的属性

2 个答案:

答案 0 :(得分:2)

1-您有3个指针指向同一对象。一个就足够了。真的!

2-只要正确实现了ark,您就可以从QML访问ark.commark.modb,而无需单独公开它们。

3-您似乎不了解id的范围。看看这个exhaustive answer。无论您在哪里建立连接,dataShow都是看不见的。

4-上下文属性不是很有效,更多的是将C ++暴露给qml的“快速而肮脏的”方法。为了获得最佳性能,请考虑使用more efficient approach

总而言之,您表现出“超越自己”的典型症状。在练习之前,花点时间学习。

答案 1 :(得分:1)

您确实假设您也可以在其他qml中使用modb变量,因为它已添加到rootContext中。我建议您使用此选项。

您可以尝试的另一种选择是使用dataArea.text = string,因为id遍地都是(毕竟是javascript),在这种情况下,您应该使用强id。

另一个选择是定义property alias,以使字符串在对象(See Qt docs)上传递。或使用property string,但这还需要更多工作。