Search code examples
functionlistviewqml

QML: define function in ListElement called in ListView


Inside a QML ListView, i'd like to call a function when a MouseArea is clicked:

ListView{
    anchors.fill: parent
    orientation: ListView.Horizontal

    model: myModel

    delegate:
    Rectangle {
        anchors.fill: parent
        Text {
            anchors.centerin: parent
            text: label
        }
        MouseArea {
            width: 30
            height: parent.height
            onClicked: {
                doSomething()
            }
        }
    }
}

I's supposed to be an overflow-menu. In the ListModel (myModel) i want to be able to say what happens when doSomething() is called. How do i do that? Maybe like so?

ListModel {
    id: myModel

    ListElement {
        label: "New"
        doSomething: {
            canvas.clear()
        }
    }
}

I have no idea. I searched the web, but i couldn't find anything.
I'm using a ListView/Model for this because i want to add and remove menu-entries dynamically.
Thanks for your attention! =)


Solution

  • qrc:///main.qml:49 ListElement: cannot use script for property value

    That's what you get with your code. So you can't set any property of a model element as a script.

    I got away with it by putting the functions in the model, not the model element:

    ListView{
        anchors.fill: parent
        orientation: ListView.Horizontal
    
        model: myModel
    
        delegate:
        Rectangle {
            anchors.fill: parent
            color: "red"
            Text {
                anchors.centerIn: parent
                text: label
            }
            MouseArea {
                anchors.centerIn: parent
                width: 30
                height: parent.height
                onClicked: {
                    myModel.actions[label]();
                }
            }
        }
    }
    
    ListModel {
        id: myModel
    
        property var actions : {
            "New": function(){ console.log("clicked!"); }
        }
    
        ListElement {
            label: "New"
        }
    }
    

    Though indexing actions based on text is kind of meh, you should probably make it so each element in the model has a unique property (like an index) and use those as the keys for the actions dictionnary.

    (on a side note, you forgot the centerIn of the mouse area, and I wonder why you use a width of 30 instead of just filling the parent)