Add item to ListModel at run-time
-
Hi all,
Here's a simplified version of a bigger code:
import QtQuick import QtQuick.Controls Window { width: 640 height: 480 visible: true title: qsTr("Hello World") Column { spacing: 10 Button { text: qsTr("Add Item") font.pixelSize: 15 onClicked: listMd.append({ "name": txtField.text triggered: function() { console.log("One") } }) } TextField { id: txtField } } Rectangle { id: root anchors.centerIn: parent width: 200; height: 150 color: "lightblue" ListModel { id: listMd ListElement { name: qsTr("One") triggered: function() { console.log("One") } } ListElement { name: qsTr("Two") triggered: function() { console.log("Two") } } } Component { id: nameDelegate Text { text: model.name font.pixelSize: 32 MouseArea { anchors.fill: parent onClicked: model.triggered() } } } ListView { id: lsView anchors.fill: parent model: listMd delegate: nameDelegate clip: true focus: true } } }
I've got two questions:
- How to modify the list elements so that the console.log function prints the name of the element? I tried:
ListElement { name: qsTr("One") triggered: function() { console.log(model.name) } }
But I get this error: ReferenceError: model is not defined
- How to add and new element using the button and text field in the code please? I tried using append() but it's not working properly.
-
@qcoderpro said in Add item to ListModel at run-time:
How to modify the list elements so that the console.log function prints the name of the element? I tried:
ListElement { name: qsTr("One") triggered: function() { console.log(name) } }
What happens if you put triggered in quotes?
onClicked: listMd.append({ "name": txtField.text "triggered": function() { console.log("One") } })
Are you getting any console errors?
https://doc.qt.io/qt-5/qml-qtqml-models-listmodel.html#append-method
It shows field names in quotes. The quotes seem kinda odd to me. -
@qcoderpro said in Add item to ListModel at run-time:
How to modify the list elements so that the console.log function prints the name of the element? I tried:
ListElement { name: qsTr("One") triggered: function() { console.log(name) } }
What happens if you put triggered in quotes?
onClicked: listMd.append({ "name": txtField.text "triggered": function() { console.log("One") } })
Are you getting any console errors?
https://doc.qt.io/qt-5/qml-qtqml-models-listmodel.html#append-method
It shows field names in quotes. The quotes seem kinda odd to me.Are you getting any console errors?
Yes, I get
Expected token '}'
error for the line triggered!I tried this:
// ... Button { text: qsTr("Add Item") font.pixelSize: 15 onClicked: listMd.append( { name: txtField.text, triggered: function() { console.log("new Item") } }) } // ...
When I type "Three" in the text field and click on Add Item the text will be added to the list, but I also get the error: <Unknown File>: Can't assign to existing role 'triggered' of different type [VariantMap -> Function]
-
@qcoderpro said in Add item to ListModel at run-time:
Can't assign to existing role 'triggered' of different type [VariantMap -> Function]
It is seeing the ListElement "triggered" as something different than the append version of "triggered". So a work around is to add the initial elements via Component.onCompleted:
import QtQuick 2.15 import QtQuick.Controls 2.15 import QtQuick.Window 2.15 Window { width: 640 height: 480 visible: true title: qsTr("Hello World") Column { spacing: 10 Button { text: qsTr("Add Item") font.pixelSize: 15 onClicked: listMd.append({ name: txtField.text, triggered: function() { console.log(txtField.text) } }) } TextField { id: txtField } } Rectangle { id: root anchors.centerIn: parent width: 200; height: 150 color: "lightblue" ListModel { id: listMd /* ListElement { name: qsTr("One") triggered: function() { console.log("One") } } ListElement { name: qsTr("Two") triggered: function() { console.log("Two") } } */ Component.onCompleted: { listMd.append({ name: "One", triggered: function() { console.log("One") }}) listMd.append({ name: "Two", triggered: function() { console.log("Two") }}) } } Component { id: nameDelegate Text { text: model.name font.pixelSize: 32 MouseArea { anchors.fill: parent onClicked: model.triggered() } } } ListView { id: lsView anchors.fill: parent model: listMd delegate: nameDelegate clip: true focus: true } } }
When clicking the text it does not run the function:
qrc:/main.qml:62: TypeError: Property 'triggered' of object QQmlDMAbstractItemModelData(0x55ed97edb360) is not a function
The conversion of the object in append is turning the function into an object of some type. I have seen ListModel convert other objects before when using append. So I don't think this approach will work this way.You could insert a string for the triggered property. Then use that string to lookup the function you want to call. You could store the function lookup object anywhere. The problem is now you have 2 lists. So maybe that isn't a good solution.
(For the future, when posting minimal code, please check that it runs. There was stuff missing in the first post.)