如何在QML中访问和更改Component中的项目

时间:2017-06-16 07:45:21

标签: qt qml components

在Qml文件中,代码如下:

StackView {
    id: stackView
    anchors.right: parent.right
    width: parent.width/2-20
    initialItem:patientdetail

    Component{
        id:patientdetail
        Column {
            id:detailcolumn
            spacing: 2
            anchors.right: parent.right
            width: parent.width/2-20

            Label {
                id: label
                color: "#ffffff"
                text: qsTr("User ID")
            }

            TextField {
                id: textField_id
                readOnly: true
                placeholderText: qsTr("")
            }
        }
      }
    Component{
        id:component2
        //...other component will add to stackview
      }
   }

我想通过JS函数(在同一个文件中)更改TextField的文本,如:

function updatedetail(clear,rowindex){
    if(clear){
        textField_id.text="";
    }
    else{
        textField_id.text=jsonModel1.model.get(rowindex).id;
    }
}

但是有一个错误:

  

ReferenceError:未定义textField_id

错误发生的地方?

1 个答案:

答案 0 :(得分:3)

当您尝试更改尚未实例化的对象时,它将失败。但即使它被实例化,它的id也将处于不同的范围内,这是不可能达到的。
这是必要的,因为相同的Component可能会被多次实例化(例如delegate中的ListView),因此它不再是上下文中唯一的。

StackView进行实例化,您的Component将被StackView推送实例化。现在您有了一个实例,可能会使用以下方法更改公开的属性:

currentItem.textFieldText = newValue

在你的功能中。为此,您需要公开属性:

Component{
    id:patientdetail
    Column {
        id:detailcolumn
        spacing: 2
        anchors.right: parent.right
        width: parent.width/2-20

        property alias textFieldText: textField_id.text // in this context, you have access to the id. Expose it, to change it from the outside.

        Label {
            id: label
            color: "#ffffff"
            text: qsTr("User ID")
        }

        TextField {
            id: textField_id
            readOnly: true
            placeholderText: qsTr("")
        }
    }
}

但是,由于实例可能会被销毁并在以后重新创建,因此此更改不会是永久性的,因此最好将TextField.text绑定到对象的属性,该属性将在必要时存活。这可以是从C ++公开的contextProperty或作为模型传递的QtObject,或者只是属性,例如在StackView

StackView {
    id: stackView
    anchors.right: parent.right
    width: parent.width/2-20
    initialItem:patientdetail

    // Change this property. The textField_id.text will be bound to it.
    property string textFieldText

    Component{
        id:patientdetail
        Column {
            id:detailcolumn
            spacing: 2
            anchors.right: parent.right
            width: parent.width/2-20

            Label {
                id: label
                color: "#ffffff"
                text: qsTr("User ID")
            }

            TextField {
                id: textField_id
                readOnly: true
                placeholderText: qsTr("")
                text: stackView.textFieldText
            }
        }
    }
}