2

I have a 100 element of same type in My QML File with the ids of "input0" to "input99" that has a property with type of string named text and i want to use a loop to push all the string into a array in JavaScript i tried to use a loop like this and but nothing works and the array remains empty:

function gather(){
var array=[]
for (var i =0;i<100;i++){
{array.push(("input"+i).text;
console.log(array[i];}
}

I get the following log:

(gather): qml: undefined

I'm on QtQuick 2.7

how can i do this ?

EDIT: With the suggestion of derM it tried the following:

Flickable{
    TextField{
        id:input1
        text:"text1"
    }
    TextField{
        id:input2
        text:"text2"
    }
    TextField{
        id:input3
        text:"text3"
    }
    TextField{
        id:input4
        text:"text4"
    }
    Component.onCompleted: {
        var textArray=[]
        for (var i = 1; i < 5; i++) {
            var c = Qt.createQmlObject("import QtQuick 2.0; QtObject { function f() { return input" + i + ".text } }", this, "none")
            textArray.push(c.f())
            console.log(textArray[i])
            c.destroy()
        }
    }
}

It still does not work. What have I done wrong?

4
  • Are those inputs children to an Item? Commented May 7, 2017 at 14:06
  • its TextField most of the elements Commented May 7, 2017 at 15:18
  • I was not asking, what kind of Items your inputs are. I was asking for their parent. Are they all children of the same Item or not? Commented May 7, 2017 at 15:54
  • they are children to a gridLayout Commented May 8, 2017 at 18:25

1 Answer 1

1

If you really want/need to grab them by id you need to translate from a string to an id, which is not very performant, and can't be done with ('myStringHere').

The only way I can think of right now, is dynamic object creation with Qt.createQmlObject() where you create a dummy object, containing a function, that returns the desired object.

Example:

import QtQuick 2.6
import QtQuick.Window 2.2

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("PathView path test")

    Text {
        id: myText1
        text: "hallo"
    }

    Text {
        id: myText2
        text: "world"
    }

    Text {
        id: myText3
        text: "and"
    }

    Text {
        id: myText4
        text: "stuff"
    }

    property var textArray: []

    Component.onCompleted: {
        for (var i = 1; i < 5; i++) {
            var c = Qt.createQmlObject("import QtQuick 2.0; QtObject { function f() { return myText" + i + ".text } }", this, "none")
            textArray.push(c.f())
            c.destroy()
        }
        console.log(textArray)
    }
}

But as this dynamic object creation is not the most performant, I would rather not do it.

If by chance, all of those inputXX are children of the same parent, you might instead just crawl the parent's children-property. If you need to make sure, that the id is proper, also set the objectName to be the same as the id, as you can't query the id.

EDIT As all the inputs are children to the same GridLayout you can proceed with the second approach: looping over the GridLayout.children like this:

function collectTexts() {
    var a = []
    for (var i = 0; i < children.length; i++) {
        if (children[i].text) {
            a.push(children[i].text)
        }
    }
    return a
}

As there might be other children that have a text-property, it is advisable to set the objectName-property e.g. to inputXX and check if the objectName matches this pattern before adding it to the array.


EDIT: Regarding your second try

In the code, where you tried to adapt my solution, the parts of my code are fine. What does not work is, how you handle the array.

Your loop starts with i = 1. So you successfully push input1.text into the array. The indices of the array however start with 0, so the first element that you just pushed is in textArray[0] - you print textArray[1] which is still undefined - thus this output. You can fix that code by simply replacing the line

console.log(textArray[i])

by

console.log(textArray[i - 1])
Sign up to request clarification or add additional context in comments.

13 Comments

Dynamic Object creation cannot work cause every input has a different name and position on the screen
You only create dummy objects, that will do the accessing for you, not the inputs themselves. The only thing you need to make sure of, is that the dynamic objects are in the correct scope, to resolve the id names.
You should try out suggested code, before saying, it would not work.
i tried it and i added console.log after push to see the entery and i still get (onCompleted): qml: undefined even with text in it.
Please share the code of your last attempt. Maybe I can help you fix it. Please share a mcve
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.