How to access a ListView's ListModel's ListElement's mapped delegate's data in QML?

10,547

Solution 1

You can't access delegates in that way because they are transient objects that are created and destroyed at the discretion of the ListView. As explained in the documentation for delegates:

Delegates are instantiated as needed and may be destroyed at any time. State should never be stored in a delegate.

Is there a particular reason why you can't just add a textEnabled flag to the ListModel? For example:

import QtQuick 1.0

Rectangle {
    id: mylist
    width:300
    height:300

    ListModel {
        id: mylistModel
        ListElement {
            name: "blah1"
            textEnabled:false
        }
        ListElement {
            name: "blah2"
            textEnabled:false
        }
        ListElement {
            name: "blah3"
            textEnabled:false
        }
    }

    Component {
        id: mylistDelegate

        Text {
            id: mylistDelegateText
            text: name
            color: textEnabled?"red":"black"


            MouseArea {
                anchors.fill:parent;
                onClicked: {
                    mylistModel.setProperty(index, "textEnabled", !textEnabled);
                }
            }
        }
    }

    ListView {
        id: mylistView
        model: mylistModel
        delegate: mylistDelegate
        width:100;
        height:100

    }      
}

Solution 2

Try this code:-

 for (var i = 0; i < mylistView.count; i ++) {
      // this will get list item at index i
      console.log(mylistView.contentItem.children[i]);

      // lets set it height to 100
      mylistView.contentItem.children[i].height=100;
   }

Hope this helps, cheers!!! @navi

Share:
10,547

Related videos on Youtube

svenstaro
Author by

svenstaro

Freelance consultant, Arch Linux developer, hobbyist game and graphics programmer

Updated on June 04, 2022

Comments

  • svenstaro
    svenstaro about 2 years

    Essentially, I have an usual ListView:

    Rectangle {
        id: mylist
    
        ListModel {
            id: mylistModel
            ListElement {
                text: "blah1"
            }
            ListElement {
                text: "blah2"
            }
            ListElement {
                text: "blah3"
            }
        }
    
        Component {
            id: mylistDelegate
    
            Text {
                id: mylistDelegateText
                text: text
                property bool mylistDelegateTextEnabled: false
            }
        }
    
        ListView {
            id: mylistView
            model: mylistModel
            delegate: mylistDelegate
        }
    }
    

    Please ignore any problems I might have introduced by truncating the code to focus on what's important.

    Anyway, now my problem is that I want to access a ListElement's assigned delegate and see what the value of mylistDelegateTextEnabled is in a javascript loop. For instance, this loop iterates over current list and gives me the text of the ListElements in the model:

    for(var i = 0; i < mylistModel.count; ++i) {
        console.log(mylistModel.get(i).text);
    }
    

    This obviously works fine.

    Now what I want is essentially this:

    for(var i = 0; i < mylistModel.count; ++i) {
        console.log(mylistModel.get(i).text);
        console.log(mylistModel.get(i).delegate.mylistDelegateTextEnabled);
    }
    

    Alas, that it doesn't seem to be that easy.

    Help appreciated.

  • svenstaro
    svenstaro over 12 years
    Thanks for the answer! I tried that and get Error: Cannot assign to read-only property "textEnabled". Yes, I'd like to do assign from QML instead of JS. Can I do that?
  • Paul Drummond
    Paul Drummond over 12 years
    I think from the error you are trying to set the textEnabled flag from within the delegate which won't work. Instead, update the model directly using model.setProperty(). I will update my answer to demonstrate it this way rather than using Component.onCompleted.