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. Is it possible to dynamically assign a component?
Forum Updated to NodeBB v4.3 + New Features

Is it possible to dynamically assign a component?

Scheduled Pinned Locked Moved Solved QML and Qt Quick
17 Posts 7 Posters 1.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.
  • mzimmersM Offline
    mzimmersM Offline
    mzimmers
    wrote on last edited by
    #1

    Hi all -

    Is there some way to do this?

    Component {
    	id: loaderComponent
    	Pump {} // can I assign this with a variable or property?
    }
    

    Thanks...

    1 Reply Last reply
    0
    • fcarneyF Offline
      fcarneyF Offline
      fcarney
      wrote on last edited by
      #2

      "dynamically assign"
      What does this mean?

      C++ is a perfectly valid school of magic.

      1 Reply Last reply
      0
      • mzimmersM Offline
        mzimmersM Offline
        mzimmers
        wrote on last edited by
        #3

        Hi @fcarney - the snippet is from a file that gets used for many pieces of equipment: pump, filter, cleaner, etc. In my example, I'd like to replace "Pump" with a variable or something that I can pass into this file through a property.

        1 Reply Last reply
        0
        • JoeCFDJ Offline
          JoeCFDJ Offline
          JoeCFD
          wrote on last edited by JoeCFD
          #4

          is it like you define a property string or int in Pump and replace it here?

          mzimmersM 1 Reply Last reply
          0
          • JoeCFDJ JoeCFD

            is it like you define a property string or int in Pump and replace it here?

            mzimmersM Offline
            mzimmersM Offline
            mzimmers
            wrote on last edited by
            #5

            @JoeCFD what I'm trying to do is eliminate the hard-coding of the Pump within the Component.

            Component {
            	id: loaderComponent
            	Pump {} // can I use a variable instead of saying "Pump"?
            }
            
            1 Reply Last reply
            0
            • B Offline
              B Offline
              Bob64
              wrote on last edited by
              #6

              Have you looked at createComponent and createObject?

              mzimmersM 1 Reply Last reply
              0
              • B Bob64

                Have you looked at createComponent and createObject?

                mzimmersM Offline
                mzimmersM Offline
                mzimmers
                wrote on last edited by
                #7

                @Bob64 yes I have looked at those. I can go that route if necessary -- I just wanted to see if I was overlooking something far simpler (which I often do).

                I tried this:

                        Loader {
                            id: drawerLoader
                            active: drawer.opened
                        }
                        Component.onCompleted: {
                            drawerLoader.setSource(tile.drawerFile,
                                                   {"titleText": tile.titleText})
                        }
                

                Curiously, this loaded the file, but my argument didn't come through...

                1 Reply Last reply
                0
                • dheerendraD Offline
                  dheerendraD Offline
                  dheerendra
                  Qt Champions 2022
                  wrote on last edited by
                  #8

                  This is not possible. Better you can look at createQmlObject(..). You can build string dynamically & use for creation of objects.

                  Dheerendra
                  @Community Service
                  Certified Qt Specialist
                  http://www.pthinks.com

                  1 Reply Last reply
                  1
                  • mzimmersM Offline
                    mzimmersM Offline
                    mzimmers
                    wrote on last edited by
                    #9

                    Let me ask the question differently, since I still have the feeling I'm overcomplicating this.

                    I want a QML object that I can reuse. The object will contain a Drawer, the contents of which will be different for each instance of the object. I also need to pass arguments into the object. How best to do this?

                    Thanks...

                    TomZT 1 Reply Last reply
                    1
                    • JoeCFDJ Offline
                      JoeCFDJ Offline
                      JoeCFD
                      wrote on last edited by JoeCFD
                      #10

                      sounds like you need a model for qml object. The arguments can be defined or stored in the model. Different models are applied to the qml. Check XmlListModel or VisualItemModel out to see if it helps.

                      1 Reply Last reply
                      0
                      • mzimmersM mzimmers

                        Let me ask the question differently, since I still have the feeling I'm overcomplicating this.

                        I want a QML object that I can reuse. The object will contain a Drawer, the contents of which will be different for each instance of the object. I also need to pass arguments into the object. How best to do this?

                        Thanks...

                        TomZT Offline
                        TomZT Offline
                        TomZ
                        wrote on last edited by
                        #11

                        @mzimmers said in Is it possible to dynamically assign a component?:

                        I want a QML object that I can reuse. The object will contain a Drawer, the contents of which will be different for each instance of the object. I also need to pass arguments into the object. How best to do this?

                        Declarative-ly.

                        Take a look at the 'model' property in Repeater, for instance.

                        If this is specifically about a Loader, you can use the 'item' property and the onLoaded callback.

                        Loader {
                            id: foo
                            onLoaded: {
                                item.model = something;            
                            }
                        }
                        
                        mzimmersM 1 Reply Last reply
                        1
                        • TomZT TomZ

                          @mzimmers said in Is it possible to dynamically assign a component?:

                          I want a QML object that I can reuse. The object will contain a Drawer, the contents of which will be different for each instance of the object. I also need to pass arguments into the object. How best to do this?

                          Declarative-ly.

                          Take a look at the 'model' property in Repeater, for instance.

                          If this is specifically about a Loader, you can use the 'item' property and the onLoaded callback.

                          Loader {
                              id: foo
                              onLoaded: {
                                  item.model = something;            
                              }
                          }
                          
                          mzimmersM Offline
                          mzimmersM Offline
                          mzimmers
                          wrote on last edited by
                          #12

                          @TomZ thanks for the suggestion. Are you sure your code example is correct? I tried this:

                              Loader {
                                      id: drawerLoader
                                      active: drawer.opened
                                      source: tile.drawerFile
                                      onLoaded: {
                                             item.model = 10;
                                         }
                                  }
                          

                          And got an error: Error: Cannot assign to non-existent property "model"

                          1 Reply Last reply
                          0
                          • TomZT Offline
                            TomZT Offline
                            TomZ
                            wrote on last edited by
                            #13

                            Loader takes a source property which points to your re-usable QML component. (or sourceComponent, check the docs).

                            The actual reusable QML component in my example is not listed. It would be the one that has a property QtObject model: null or similar, which it uses internally to 'do stuff'.

                            My example is thus purely meant to illustrate the way for you to assign your data to the re-usable component you would write yourself.

                            mzimmersM 1 Reply Last reply
                            0
                            • TomZT TomZ

                              Loader takes a source property which points to your re-usable QML component. (or sourceComponent, check the docs).

                              The actual reusable QML component in my example is not listed. It would be the one that has a property QtObject model: null or similar, which it uses internally to 'do stuff'.

                              My example is thus purely meant to illustrate the way for you to assign your data to the re-usable component you would write yourself.

                              mzimmersM Offline
                              mzimmersM Offline
                              mzimmers
                              wrote on last edited by
                              #14

                              Hey everybody -

                              Thanks for all the good suggestions. I fill file them away for future use. For my current issue, here's how I solved it:

                              Rectangle {
                                  id: tile
                              
                                  property url drawerFile: "" // supplied by caller
                                  property string titleText: "" // supplied by caller
                                  property string statusText: "" // supplied by caller
                              
                                  Drawer {
                                      id: drawer
                                      
                                      Loader {
                                          id: drawerLoader
                                          anchors.fill: parent
                                          active: drawer.opened
                                          source: tile.drawerFile
                                          onLoaded: {
                                              item.titleText = tile.titleText
                                              item.statusText = tile.statusText
                                          }
                                      }
                                  }
                              }
                              

                              This is what I was looking for: both the item itself (tile.drawerfile) and arguments to the item (item.titleText and item.statusText) can be expressed with variables (properties).

                              Thanks again...

                              kshegunovK 1 Reply Last reply
                              0
                              • mzimmersM mzimmers

                                Hey everybody -

                                Thanks for all the good suggestions. I fill file them away for future use. For my current issue, here's how I solved it:

                                Rectangle {
                                    id: tile
                                
                                    property url drawerFile: "" // supplied by caller
                                    property string titleText: "" // supplied by caller
                                    property string statusText: "" // supplied by caller
                                
                                    Drawer {
                                        id: drawer
                                        
                                        Loader {
                                            id: drawerLoader
                                            anchors.fill: parent
                                            active: drawer.opened
                                            source: tile.drawerFile
                                            onLoaded: {
                                                item.titleText = tile.titleText
                                                item.statusText = tile.statusText
                                            }
                                        }
                                    }
                                }
                                

                                This is what I was looking for: both the item itself (tile.drawerfile) and arguments to the item (item.titleText and item.statusText) can be expressed with variables (properties).

                                Thanks again...

                                kshegunovK Offline
                                kshegunovK Offline
                                kshegunov
                                Moderators
                                wrote on last edited by kshegunov
                                #15

                                I imagine what you want is something of this sort:

                                Item
                                {
                                    id: tile
                                    property alias delegate: loader.source
                                    property alias opened: loader.active
                                    property string titleText: ""
                                    property string statusText: ""
                                
                                    Loader {
                                        id: loader
                                        anchors.fill: parent
                                        active: false
                                        onLoaded: {
                                            item.titleText = Qt.binding(function() { return tile.titleText })
                                            item.statusText = Qt.binding(function() { return tile.statusText })
                                        }
                                    }
                                }
                                

                                You do want the property to update if/when it's changed, and also not to define properties needlessly - just alias what you can.

                                PS.
                                Or even better would be to alias sourceComponent of the Loader, not the url proper.

                                Read and abide by the Qt Code of Conduct

                                mzimmersM 1 Reply Last reply
                                1
                                • kshegunovK kshegunov

                                  I imagine what you want is something of this sort:

                                  Item
                                  {
                                      id: tile
                                      property alias delegate: loader.source
                                      property alias opened: loader.active
                                      property string titleText: ""
                                      property string statusText: ""
                                  
                                      Loader {
                                          id: loader
                                          anchors.fill: parent
                                          active: false
                                          onLoaded: {
                                              item.titleText = Qt.binding(function() { return tile.titleText })
                                              item.statusText = Qt.binding(function() { return tile.statusText })
                                          }
                                      }
                                  }
                                  

                                  You do want the property to update if/when it's changed, and also not to define properties needlessly - just alias what you can.

                                  PS.
                                  Or even better would be to alias sourceComponent of the Loader, not the url proper.

                                  mzimmersM Offline
                                  mzimmersM Offline
                                  mzimmers
                                  wrote on last edited by
                                  #16

                                  @kshegunov thanks for the suggestions. I'm curious why you think it would be better to use sourceComponent instead of source.

                                  kshegunovK 1 Reply Last reply
                                  0
                                  • mzimmersM mzimmers

                                    @kshegunov thanks for the suggestions. I'm curious why you think it would be better to use sourceComponent instead of source.

                                    kshegunovK Offline
                                    kshegunovK Offline
                                    kshegunov
                                    Moderators
                                    wrote on last edited by kshegunov
                                    #17

                                    @mzimmers said in Is it possible to dynamically assign a component?:

                                    @kshegunov thanks for the suggestions. I'm curious why you think it would be better to use sourceComponent instead of source.

                                    It's much more flexible. I can define the component in the source of the user file (the QML that uses the above), or I can instantiate it from a QML file by name, or - god forbid ;) - expose it from C++ ...

                                    e.g.

                                    Component {
                                       id: someComponent
                                       ComboBox {}
                                    }
                                    
                                    MyTile {
                                       delegate: someComponent
                                       opened: true
                                       titleText: "whatever"
                                    }
                                    

                                    Read and abide by the Qt Code of Conduct

                                    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