Paweł Krakowiak
Paweł Krakowiak

Reputation: 368

How to initialize qml property list in a loop?

I have the qml list property:

Item {
    property list<SomeItem> items: [
        SomeItem { num: 0 },
        SomeItem { num: 1 },
        SomeItem { num: 2 },
        ...
        SomeItem { num: 100 }
    ]

Is it possible to initialize it in more clever way? E.g. in some way like the code below?

Item {
    property list<SomeItem> items

    ...

    Component.onCompleted: {
        for(var i = 0; i < 100; i++)
            ??? // items.append( SomeItem {num: i})
    }
}

EDIT: Sorry for the id, I actually want to change my custom property (num) which is used to initialize other properties:

SomeItem {
    property int num: 0

    key: getKey(num)
    name: getName(num)

    function getKey(num) {
        return ...
    }

    function getName(num) {
        return ...
    }
}

EDIT 2 (according to Mitch and ddriver answers): I would like to use Repeater, however I have to initialize the list property which is provided by some external library.

I've been initializing SomeItem with num property because the key property must be unique and not null. However let's say I can cope with it by setting the num in onCompleted method:

Item {
    property list<SomeItem> items: [
        SomeItem { },
        SomeItem { },
        SomeItem { },
        ...
        SomeItem { }
    ]

    ...

    Component.onCompleted: {
        for(var i = 0; i < items.length; i++)
            items[i].num = i
    }
}

So the main problem is that I have to add the SomeItem {}, line 100 times. Is there any clever way to create such property list dynamically?

Upvotes: 1

Views: 4527

Answers (2)

dtech
dtech

Reputation: 49319

What you try to do makes no sense. And is completely redundant. And impossible.

The id property is not a string, nor can it be a number.

In your particular case you want a number id equal to the index of each object in the list, which aside from impossible is also unnecessary. Instead you can access each object easily by using items[index].

If for some reason you really need to assign and use dynamic identifiers, you can use a JS object, which will allow you to do string key lookup rather than integer index:

    Item {        
        property var lookup: new Object

        Component {
            id: test

            QtObject {
                property string name
            }
        }

        Component.onCompleted: {
            lookup["John"] = test.createObject(null, { "name" : "JohnDoe" })
            lookup["Jane"] = test.createObject(null, { "name" : "JaneDoe" })

            console.log(lookup["John"].name) // outputs JohnDoe
            console.log(lookup["Jane"].name) // outputs JaneDoe
        }
    }

Upvotes: 1

Mitch
Mitch

Reputation: 24416

No.

The documentation for list describes the ways that it can be used:

A list value can be accessed in a similar way to a JavaScript array:

  • Values are assigned using the [] square bracket syntax with comma-separated values
  • The length property provides the number of items in the list
  • Values in the list are accessed using the [index] syntax

You're better off using a Repeater:

Repeater {
    model: 100

    delegate: SomeItem {
        num: index
    }
}

Upvotes: 3

Related Questions