1
votes

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! =)

1
What is your goal, exactly? Trigger a modification of the model w.r.t. the outcome of doSomething() or modifying the model from doSomething()? - BaCaRoZzo
I don't want to modify the model at all. It's supposed to be an overflow-menu. each entry should do something when you click it. Let me edit the main-post. - PH-zero

1 Answers

5
votes

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)