How to access delegate properties in ListView using index

14,898

Solution 1

First of all: if you are trying to access list elements from outside your list, this is a good indicator that you should rethink your desing.

Now the solution: a listview has more children than only its items. You can filter them out by defining a property "property string type: "myType" " for example. Then find the items by looping over the children and only take those where the type property equals "myType". Its somewhat of a hack but again you should really not be doing this in the first place.

Solution 2

@Teimpz didn't really explain it well. Especially since there are bunch of qt project and ubuntu touch qml examples and use cases where you manage dynamically created list elements using javascript, and that is why they have javascript methods and properties

In QML there is more a notion of parent than a child, which is common in html. In bigger projects it is recommended (as you can also see in qt examples and in docs http://doc.qt.io/qt-5/qtqml-javascript-expressions.html#functions-in-imported-javascript-files) to have js logic separate from qml elements so you do access and manage elements from outside rather than pollute you qml elements with js logic, but not in a way of looking for children elements, but rather exposing children elements that you need.

In your case you should just use currentItem, same as you use currentIndex, so currentItem.count will give you what you need. And if you don't need current item at all, you can access elements from model directly:

modelData.get(currentIndex).count, or listview.model.get(currentIndex).count

As for the hack that is mentioned by @Teimpz that is also one bad example. When you have more complex requirements and wanting specific elements inside delegate, every delegate has ListView.isCurrentItem property which you can attach and check. This would mean you can add property var myTargetItem to listview, and set it from child to whatever element you want if that delegate is current http://doc.qt.io/qt-5/qml-qtquick-listview.html#isCurrentItem-attached-prop

You can of course do that for any kind of event, maybe activeFocus so you could only reference activeFocused item.

This once again give you ability to expose only wanted elements without any advanced logic or lopping. Combining this with signals you can create very complex but clean interfaces without searching through children items.

So in the end maybe less nice but still better than searching for elements would be to add property int currentItemCount: 0 to listview. In delegate (Row element) you then add property bool isCurrentItem: ListView.isCurrentItem so you get onIsCurrentItemChanged signal inside delegate, where you can do: onIsCurrentItemChanged: if(isCurrentItem) listview.currentItemCount = count so you have your current item count always set

Share:
14,898

Related videos on Youtube

Jeggu
Author by

Jeggu

Updated on October 26, 2022

Comments

  • Jeggu
    Jeggu over 1 year

    I want to access delegate properties in ListView. I've tried with contentItem but sometimes it's undefined.

    Here is my code:

    ListModel{
                id: modeldata
                ListElement{
                    name:"don"
                    rank:1
                }
                ListElement{
                    name:"shan"
                    rank:2
                }
                ListElement{
                    name:"james"
                    rank:3
                }
                ListElement{
                    name:"jeggu"
                    rank:4
                }
            }
            Component{
                id: delegateitem
                Row {
                    property int count: rank
                    Rectangle{
                        width: 100
                        height: 50
                        Text{
                            anchors.centerIn: parent
                            text: name
                        }
                    }
                }
            }
            ListView{
                id: listview
                focus: true
                anchors.fill: parent
                model: modeldata
                delegate: delegateitem
                onCurrentIndexChanged: {
            console.log("position",currentIndex)
            console.log("property",contentItem.children[currentIndex].count);
                }
            }
    

    Problem invalid output at position 1

    qml: position 0
    qml: property 1
    qml: position 1
    qml: property undefined
    qml: position 2
    qml: property 2
    qml: position 3
    qml: property 3
    
  • S.M.Mousavi
    S.M.Mousavi over 7 years
    thank you for useful note about separating js logic from qml.
  • Mark Ch
    Mark Ch almost 7 years
    this will be awkward to code up and slow to run. If I'm wrong, perhaps provide a code sample to demonstrate
  • Crawl.W
    Crawl.W about 5 years
    I really want to know what it is, although I know that I should go to the source.