Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Set property in a list of ListElement
Forum Updated to NodeBB v4.3 + New Features

Set property in a list of ListElement

Scheduled Pinned Locked Moved Solved QML and Qt Quick
13 Posts 3 Posters 3.2k Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    DavidM29
    wrote on last edited by
    #1

    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

    raven-worxR 1 Reply Last reply
    0
    • D DavidM29

      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

      raven-worxR Offline
      raven-worxR Offline
      raven-worx
      Moderators
      wrote on last edited by raven-worx
      #2

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

      --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
      If you have a question please use the forum so others can benefit from the solution in the future

      D 1 Reply Last reply
      0
      • raven-worxR raven-worx

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

        D Offline
        D Offline
        DavidM29
        wrote on last edited by
        #3

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

        raven-worxR 1 Reply Last reply
        0
        • D DavidM29

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

          raven-worxR Offline
          raven-worxR Offline
          raven-worx
          Moderators
          wrote on last edited by
          #4

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

          --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
          If you have a question please use the forum so others can benefit from the solution in the future

          D 2 Replies Last reply
          0
          • raven-worxR raven-worx

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

            D Offline
            D Offline
            DavidM29
            wrote on last edited by DavidM29
            #5

            @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
                        }
            
            1 Reply Last reply
            0
            • raven-worxR raven-worx

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

              D Offline
              D Offline
              DavidM29
              wrote on last edited by
              #6

              @raven-worx
              Do you have any idea on my problem ? I may be not clear on my explanation if so please ask me.

              1 Reply Last reply
              0
              • Y Offline
                Y Offline
                Yaswanth
                wrote on last edited by
                #7

                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.

                D 1 Reply Last reply
                0
                • Y Yaswanth

                  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.

                  D Offline
                  D Offline
                  DavidM29
                  wrote on last edited by DavidM29
                  #8

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

                  Y 1 Reply Last reply
                  0
                  • D DavidM29

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

                    Y Offline
                    Y Offline
                    Yaswanth
                    wrote on last edited by Yaswanth
                    #9

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

                    D 1 Reply Last reply
                    0
                    • Y Yaswanth

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

                      D Offline
                      D Offline
                      DavidM29
                      wrote on last edited by DavidM29
                      #10

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

                      D 1 Reply Last reply
                      0
                      • D DavidM29

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

                        D Offline
                        D Offline
                        DavidM29
                        wrote on last edited by
                        #11

                        @Yaswanth
                        Do you have any more ideas ?

                        Y 1 Reply Last reply
                        0
                        • D DavidM29

                          @Yaswanth
                          Do you have any more ideas ?

                          Y Offline
                          Y Offline
                          Yaswanth
                          wrote on last edited by Yaswanth
                          #12

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

                          D 1 Reply Last reply
                          0
                          • Y Yaswanth

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

                            D Offline
                            D Offline
                            DavidM29
                            wrote on last edited by DavidM29
                            #13

                            @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

                            1 Reply Last reply
                            0

                            • Login

                            • Login or register to search.
                            • First post
                              Last post
                            0
                            • Categories
                            • Recent
                            • Tags
                            • Popular
                            • Users
                            • Groups
                            • Search
                            • Get Qt Extensions
                            • Unsolved