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. How to set value to dynamically loaded component?
Forum Updated to NodeBB v4.3 + New Features

How to set value to dynamically loaded component?

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
4 Posts 2 Posters 280 Views
  • 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.
  • Y Offline
    Y Offline
    ynatynat
    wrote on last edited by ynatynat
    #1

    I could load components dynamically, but can't set value to each component.
    How to set value to each property of component from property of model ?

    import QtQuick 2.15
    import QtQuick.Controls 2.15
    import QtQuick.Layouts 1.15
    
    Item {
    
        ListModel{
            id:model_params
            ListElement{
                _type:"spin"
                _name:"paramA"
                _val:5
            }
            ListElement{
                _type:"spin"
                _name:"paramB"
                _val:34
            }
            ListElement{
                _type:"combo"
                _name:"paramC_COMBO"
                _val:1
                _choice:[
                    ListElement{
                        _elem:"A"
                    },
                    ListElement{
                        _elem:"B"
                    }
                ]
    
            }
        }
        anchors.centerIn: parent
        width:parent.width
        height:parent.height-80
    
        anchors.fill: parent
        GridView{
            id:grid
            width:parent.width;height:parent.height
            anchors.fill: parent
    
            model:model_params
            cellWidth:parent.width/3
            cellHeight:parent.height/10
            reuseItems:true
            flow:GridView.FlowTopToBottom
    
            delegate:Component{
    
                Loader{
                    width:parent.width
    
                    sourceComponent: _type==="spin"?spinbox:combobox
                    //how to set value to each property of component from property of model ?
                    //
                }
            }
    
    
    
    
        }
    
        Component{
            id:spinbox
    
            Row{
    property string name:"dummyParamName"
                Label{
                    text:parent.name
                }
                SpinBox{
                    width:parent.width*0.5
                }
            }
        }
        Component{
            id:combobox
    
            ComboBox{
                property string name:"dummyParamName"
                width:100
                displayText: name
                model:["dummy1","dummy2"]
            }
        }
    
    
    
    }
    
    
    
    B 1 Reply Last reply
    0
    • Y ynatynat

      I could load components dynamically, but can't set value to each component.
      How to set value to each property of component from property of model ?

      import QtQuick 2.15
      import QtQuick.Controls 2.15
      import QtQuick.Layouts 1.15
      
      Item {
      
          ListModel{
              id:model_params
              ListElement{
                  _type:"spin"
                  _name:"paramA"
                  _val:5
              }
              ListElement{
                  _type:"spin"
                  _name:"paramB"
                  _val:34
              }
              ListElement{
                  _type:"combo"
                  _name:"paramC_COMBO"
                  _val:1
                  _choice:[
                      ListElement{
                          _elem:"A"
                      },
                      ListElement{
                          _elem:"B"
                      }
                  ]
      
              }
          }
          anchors.centerIn: parent
          width:parent.width
          height:parent.height-80
      
          anchors.fill: parent
          GridView{
              id:grid
              width:parent.width;height:parent.height
              anchors.fill: parent
      
              model:model_params
              cellWidth:parent.width/3
              cellHeight:parent.height/10
              reuseItems:true
              flow:GridView.FlowTopToBottom
      
              delegate:Component{
      
                  Loader{
                      width:parent.width
      
                      sourceComponent: _type==="spin"?spinbox:combobox
                      //how to set value to each property of component from property of model ?
                      //
                  }
              }
      
      
      
      
          }
      
          Component{
              id:spinbox
      
              Row{
      property string name:"dummyParamName"
                  Label{
                      text:parent.name
                  }
                  SpinBox{
                      width:parent.width*0.5
                  }
              }
          }
          Component{
              id:combobox
      
              ComboBox{
                  property string name:"dummyParamName"
                  width:100
                  displayText: name
                  model:["dummy1","dummy2"]
              }
          }
      
      
      
      }
      
      
      
      B Offline
      B Offline
      Bob64
      wrote on last edited by
      #2

      @ynatynat I think the issue is that dynamically loaded components don't get direct access to what you might expect to be the Loader's parent context. They can access properties defined locally to the Loader however and the Loader itself can access the parent scope. Therefore, in order to pass model properties to the loaded components I think you need to introduce intermediate properties local to the Loader:

             delegate:Component{
                  Loader{
                      width:parent.width
                     
                     // "Forward" the _name field from the model to loaded
                     // components via this locally defined property. "name" is
                     // accessible in the loaded components.
                     property string name: _name
                   ...
      
      Y 1 Reply Last reply
      0
      • B Bob64

        @ynatynat I think the issue is that dynamically loaded components don't get direct access to what you might expect to be the Loader's parent context. They can access properties defined locally to the Loader however and the Loader itself can access the parent scope. Therefore, in order to pass model properties to the loaded components I think you need to introduce intermediate properties local to the Loader:

               delegate:Component{
                    Loader{
                        width:parent.width
                       
                       // "Forward" the _name field from the model to loaded
                       // components via this locally defined property. "name" is
                       // accessible in the loaded components.
                       property string name: _name
                     ...
        
        Y Offline
        Y Offline
        ynatynat
        wrote on last edited by
        #3

        @Bob64
        Thank you for your comment.
        I can set name & val to each component .
        But I couldn't set model of ComboBox from loader.
        Do you know how to set?

        import QtQuick 2.15
        import QtQuick.Controls 2.15
        import QtQuick.Layouts 1.15
        
        Item {
        
            ListModel{
                id:model_params
                ListElement{
                    _type:"spin"
                    _name:"paramA"
                    _val:5
                    _choice:""
                }
                ListElement{
                    _type:"spin"
                    _name:"paramB"
                    _val:34
                    _choice:""
                }
                ListElement{
                    _type:"combo"
                    _name:"paramC_COMBO"
                    _val:1
                    _choice:[
                        ListElement{
                            _elem:"A"
                        },
                        ListElement{
                            _elem:"B"
                        }
                    ]
        
                }
            }
            anchors.centerIn: parent
            width:parent.width
            height:parent.height-80
        
            anchors.fill: parent
            GridView{
                id:grid
                width:parent.width;height:parent.height
                anchors.fill: parent
        
                model:model_params
                cellWidth:parent.width/3
                cellHeight:parent.height/10
                reuseItems:true
                flow:GridView.FlowTopToBottom
        
                delegate:Component{
        
                    Loader{
                        id:loader
                        width:parent.width
                        property string name:_name
                        property int val:_val
                        property var choice:_choice// <-ERROR " Can't assign to existing role '_choice' of different type [List -> String]"
        
                        sourceComponent: _type==="spin"?spinbox:combobox
                        onLoaded:{
                            console.log("Loaded")
                        }
                    }
                }
            }
        
            Component{
                id:spinbox
                Row{
                    //property string name:"dummyParamName"//<--------Don't set property in each component
                    Label{
                        text:name// <-Just [name] is able to acccessed from loader
                    }
                    SpinBox{
                        width:parent.width*0.5
                        value:val
                    }
                }
            }
            Component{
                id:combobox
                ComboBox{
                    //property string name:"dummyParamName"//<--------Don't set property in each component
                    width:100
                    displayText: name// <-Just [name] is able to acccessed from loader
                    model:choice// <-ERROR " Can't assign to existing role '_choice' of different type [List -> String]"
                }
            }
        }
        
        
        
        B 1 Reply Last reply
        0
        • Y ynatynat

          @Bob64
          Thank you for your comment.
          I can set name & val to each component .
          But I couldn't set model of ComboBox from loader.
          Do you know how to set?

          import QtQuick 2.15
          import QtQuick.Controls 2.15
          import QtQuick.Layouts 1.15
          
          Item {
          
              ListModel{
                  id:model_params
                  ListElement{
                      _type:"spin"
                      _name:"paramA"
                      _val:5
                      _choice:""
                  }
                  ListElement{
                      _type:"spin"
                      _name:"paramB"
                      _val:34
                      _choice:""
                  }
                  ListElement{
                      _type:"combo"
                      _name:"paramC_COMBO"
                      _val:1
                      _choice:[
                          ListElement{
                              _elem:"A"
                          },
                          ListElement{
                              _elem:"B"
                          }
                      ]
          
                  }
              }
              anchors.centerIn: parent
              width:parent.width
              height:parent.height-80
          
              anchors.fill: parent
              GridView{
                  id:grid
                  width:parent.width;height:parent.height
                  anchors.fill: parent
          
                  model:model_params
                  cellWidth:parent.width/3
                  cellHeight:parent.height/10
                  reuseItems:true
                  flow:GridView.FlowTopToBottom
          
                  delegate:Component{
          
                      Loader{
                          id:loader
                          width:parent.width
                          property string name:_name
                          property int val:_val
                          property var choice:_choice// <-ERROR " Can't assign to existing role '_choice' of different type [List -> String]"
          
                          sourceComponent: _type==="spin"?spinbox:combobox
                          onLoaded:{
                              console.log("Loaded")
                          }
                      }
                  }
              }
          
              Component{
                  id:spinbox
                  Row{
                      //property string name:"dummyParamName"//<--------Don't set property in each component
                      Label{
                          text:name// <-Just [name] is able to acccessed from loader
                      }
                      SpinBox{
                          width:parent.width*0.5
                          value:val
                      }
                  }
              }
              Component{
                  id:combobox
                  ComboBox{
                      //property string name:"dummyParamName"//<--------Don't set property in each component
                      width:100
                      displayText: name// <-Just [name] is able to acccessed from loader
                      model:choice// <-ERROR " Can't assign to existing role '_choice' of different type [List -> String]"
                  }
              }
          }
          
          
          
          B Offline
          B Offline
          Bob64
          wrote on last edited by
          #4

          @ynatynat I am not by any means an expert and someone might correct me, but I suspect that you cannot do what you have done there and nest a list of ListElements in a ListElement. Have you tried using a straightforward list of strings as the options model for your combo?

          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