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


  • Moderators

    @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 ?


  • Moderators

    @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.



  • @Yaswanth

    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)



  • @DavidM29

    dataView.model = container.model
    

    As you mentioned in your code

    model: container.model //The js list model is declared in the container and called model
    

    means you are assigning same model which you had already assigned.



  • @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
    Do you have any more ideas ?



  • @DavidM29
    Can you please check dataView.model[index].value after dataView.model = container.model?
    If value is not changing, then there must be something wrong in setting value itself.



  • @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


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.