Set property in a list of ListElement
-
Hello,
I do have a JS list as a model for a ListView.
It is the only I have found so I can translate some information inside this list.
It works well but I can't set any data in that model.
To give you a better explanation : This model is used to generate a list of option that can be (button,TextField,Switch...)
In the case of a textfield for example the idea is to be able to retrive the text in the text field. But I not able to do that for now.Can you please help me on this.
Here is the ListView :
ListView { id: dataView anchors.left: leftSpacer.right anchors.right: rightSpacer.left clip: true spacing : 2 model: container.model //The js list model is declared in the container and called model delegate: OptionDelegate{} //This delegate handle multiple types of option }
The JS list model :
property var model: [ {"type": "1","optionName" : qsTr("Button option")+trans.emptyString}, {"type": "2", "optionName": qsTr("My textfield option 1")+trans.emptyString, "unite": "L", "value": "200"}, {"type": "2", "optionName": qsTr("My textfield option2")+trans.emptyString, "unite": "min", "value": "1050"} ]
The delegate handle multiple types this way :
function bestDelegate(t) { switch(t){ case 1 : return buttonDelegate; break; case 2 : return textFieldDelegate; break; default : return console.log("Type not found") } } /* My different types of component are here */ Loader { //This call the switch case above and use the appropriate delegate id: itemDisplay anchors.fill: parent; anchors.topMargin: 2 anchors.bottomMargin: 2 sourceComponent: bestDelegate(myItem.type) }
Here is an example of the textFieldDelegate :
property var myItem: model.modelData ? model.modelData : model // This is the way I get my model values Component { id : inputDelegate TextInputOption{ //This is a Label followed by a TextField id: myTextInupt height: parent.height / 8 width: parent.width nomOption: qsTrId(myItem.optionName) + trans.emptyString //Here goes the text associated to the label text: myItem.value //This is the default value I declare in my model onTextChanged: { //Here I try to update my model value console.log("Value changed : " + text) //Here I do retrieve the right value dataView.model[index].value = text //This is not working } } }
Thank you in advance for any help
-
@DavidM29
Alternatively you can do this:property var items: [ {"type": "1","optionName" : qsTr("Button option")+trans.emptyString}, {"type": "2", "optionName": qsTr("My textfield option 1")+trans.emptyString, "unite": "L", "value": "200"}, {"type": "2", "optionName": qsTr("My textfield option2")+trans.emptyString, "unite": "min", "value": "1050"} ] ListView { model: items.length delegate: Text { text: "Type: " + items[index].type + ", optionName: " + items[index].optionName } }
Note regarding your approach: only the delegate item itself gets the model data set.
-
@raven-worx
I haven't been able to make it work that way. Maybe because my Delegate is in a seperate file ?Is that solution suppose to be able to set the data in my items list ?
Do I do it right by retrieving the data in my items list ? -
@DavidM29 said in Set property in a list of ListElement:
I haven't been able to make it work that way. Maybe because my Delegate is in a seperate file ?
oh ok, i see.
Do I do it right by retrieving the data in my items list ?
The delegate item gets a property assigned named
modelData
. -
@raven-worx
The property modelData is the one I use :model.modelData
The issue is that when I do have a delegate with an input (a state or a value from textField), I'm not able to get that value back.
I do update a textField for example and on my delegate I'm trying to change the modelData here are the differents trials I've made :
onTextChanged: { //Here I try to update my model value console.log("Value changed : " + text) //Here I do retrieve the right value dataView.model[index].value = text //This is not working }
onTextChanged: { //Here I try to update my model value console.log("Value changed : " + text) //Here I do retrieve the right value model.modelData.value = text //This is not working as well }
-
@raven-worx
Do you have any idea on my problem ? I may be not clear on my explanation if so please ask me. -
Dear @DavidM29 ,
You are using JS Key/Value pair as a model for your listview.
When you do this,dataView.model[index].value = text
data in the Key/Value pair must be changed. You can confirm this by printing the value.
But the changed value is not affected in the listview.
If you rebind the model for the listview after setting this value, your changes will be affected.
Ex:onTextChanged: { //Here I try to update my model value console.log("Value changed : " + text) //Here I do retrieve the right value dataView.model[index].value = text //This is not working dataView.model = container.model }
But on every data change listview will be rebinded for all the properties.
I suggest, if you don't have any specific reason to use js Key/Value pair array, use ListModel from QML. -
Thank you for that reply.
When you write :dataView.model = container.model
What is container.model ? Is it the delegate or the parent of my listView ?
I do have specific reason to use Js Key/Value pair array. This reason is that it is the only working solution I found to translate one of the key at runtime with the Qt version I can use (Qt5.4)
-
-
@Yaswanth
I still can't get the value in the listView side.As I said :
I do have specific reason to use Js Key/Value pair array. This reason is that it is the only working solution I found to translate one of the key at runtime with the Qt version I can use (Qt5.4)The listModel using ListElement cannot use function as listElement and my translation as the Translation function of Qt5.4 is bugged need a function that return un empty String. So I'm force to use the JS.
So I did change the value in my TextField.
I log this :onTextChanged: { console.log("Value changed : " + text) //Log the value I entered dataView.model[index].value = text //This is not working dataView.model = container.model console.log("Name : " + model.modelData.optionName) //I do log info to make sure I'm logging the right value (I do) console.log("Unite : " + model.modelData.unite) }
Then on the qml file containing the model and the list view I do that :
console.log("Window : " + container.model[4].value); //The index 4 is the one I'm playing with console.log("DataView : " + dataView.model[4].value);
And the only value I do have is the default value.
-
@Yaswanth
I just log the value and the value is not changing...EDIT :
I just tried many different thing and finally found a working solution. I directly update the container model on my value changed :container.model[index].value = text
And with that it seems that my value is set on my listview side so it is ok. Thank you for your help