John Smith
John Smith

Reputation: 302

Binding text from a TextField that belongs to a Repeater

My main.qml:

Window 
{
    visible: true
    width: 640
    height: 480
    color: "grey"

    GridLayout
    {
        anchors.fill: parent
        columns : 2
        rows    : 2

        Repeater
        {
            id: rectRepeater
            model: 3
            TextField
            {
                text: "hi"
            }

        }
    }

    Rectangle
    {
        id: r1
        width: 100
        height: 100
        x: 200
        y: 200
        border.color: "red"
        Text
        {
            id: t1
        }
    }

    Component.onCompleted:
    {
        t1.text= rectRepeater.itemAt(0).text
    }
}

The Text in the rectangle r1 displays the text at the start, but if I enter new text to the TextField, the rectangle will not be updated. How can I solve this?

Upvotes: 1

Views: 791

Answers (2)

eyllanesc
eyllanesc

Reputation: 244301

A more elegant and maintainable solution is to implement a model that reflects the changes, and then make a binding of the first element with the text that shows Text:

Window{
    visible: true
    width: 640
    height: 480
    color: "grey"
    ListModel{
        id: mymodel
    }
    Component.onCompleted: {
        for(var i=0; i<3; i++){
            mymodel.append({"text" : "hi"})
        }
    }
    GridLayout{
        anchors.fill: parent
        columns : 2
        rows    : 2
        Repeater{
            model: mymodel
            TextField{
                id: tf
                onTextChanged: model.text = tf.text
                Component.onCompleted: tf.text= model.text
            }
        }
    }
    Rectangle{
        id: r1
        width: 100
        height: 100
        x: 200
        y: 200
        border.color: "red"
        Text {
            id: t1
            text: mymodel.count > 1 ? mymodel.get(0).text : ""
        }
    }
}

Upvotes: 2

Adrien Leravat
Adrien Leravat

Reputation: 2789

What you want, is to create a binding between the two.

Component.onCompleted:
{
    t1.text = Qt.binding(function() { return rectRepeater.itemAt(0).text })
}

That being said, we would need to know exactly what you are trying to do, because creating bindings manually is an anti-pattern when not required. It is much better to bind directly, or to use signals.

Do you need the first elements, and the repeater, or is this just an test for you? What is your UI and what are you trying to achieve? This is some context worth giving for a proper answer.

One possible simpler solution

Repeater
{
    id: rectRepeater
    model: 3
    TextField
    {
        text: "hi"
        // See also `onEditingFinished` and `onValidated`
        onTextChanged: {
            if (index == 0)
                t1.text = text
        }
    }
}

For more details about the property thing, look at my answers from your other question: Qml Repeater with ids

Upvotes: 1

Related Questions