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. So close, yet so far. Why index in instatiators should be available outside the delegate.

So close, yet so far. Why index in instatiators should be available outside the delegate.

Scheduled Pinned Locked Moved Solved QML and Qt Quick
11 Posts 2 Posters 868 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.
  • fcarneyF Offline
    fcarneyF Offline
    fcarney
    wrote on last edited by
    #1

    Not sure if this is even feasible with instantiators. I will most likely have to create my own object to do this, somehow. Shouldn't be that hard, I hope.

                    Instantiator {
                        id: instantiator
    
                        property var obj_list: []
                        property var comp_list: []
    
                        delegate: instantiator.comp_list[index]
    
                        onObjectAdded: comp_list.splice(index,0,object.type)
                        onObjectRemoved: comp_list.splice(index,1)
    
                        Component.onCompleted: {
                            obj_list.push({type: connectors.opcuaconnector})
                            obj_list.push({type: StandardPoint, dataSource: "opcua://default:1/Modules/Power Supply Module/Parameters/Current"})
                        }
                    }
    

    The idea is that the instantiator can get the delegate type by index. However, index is only available inside the created delegate component. But if I use say an Item to do this then the properties from the object are not applied to the correct object.

    I don't think there is a solution here other than writing a custom object to manage instances. Which is fine. I am just lamenting how close I got with Instantiators.

    C++ is a perfectly valid school of magic.

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

      It wasn't that hard:

                     ListModel {
                          id: obj_list
      
                          dynamicRoles: false
      
                          Component.onCompleted: {
                              obj_list.insert(obj_list.count, {comptype: connectors.opcuaconnector, config: {}})
                              obj_list.insert(obj_list.count, {comptype: standardPoint_comp, config: {dataSource: "opcua://default:1/Modules/Power Supply Module/Parameters/Current"}})
                          }
                      }
      
                      Component {
                          id: standardPoint_comp
      
                          StandardPoint {
                          }
                      }
      
                      Item {
                          id: customInstantiator
      
                          property var model: obj_list
                          property var inst_list: []
      
                          function insertRow(row, object){
                              var obj = object.comptype.createObject(parent, object.config)
                              inst_list.slice(row, 0, obj)
                          }
      
                          function removeRow(row){
                              var obj = inst_list[row]
                              inst_list.slice(row, 1)
                              obj.destroy()
                          }
      
                          Connections {
                              target: obj_list
      
                              function onRowsInserted(parent, first, last) {
                                  customInstantiator.insertRow(first, obj_list.get(first))
                              }
                              function onRowsRemoved(parent, first, last) {
                                  customInstantiator.removeRow(first)
                              }
                          }
                      }
      

      C++ is a perfectly valid school of magic.

      1 Reply Last reply
      1
      • GrecKoG Offline
        GrecKoG Offline
        GrecKo
        Qt Champions 2018
        wrote on last edited by
        #3

        Why not just use a Loader as a component, you could assign it a sourceComponent according to the index.

        Also why do you have such an heterogeneous list?
        Have you looked at DelegateChooser?

        Can you describe us what's your higher level goal is? I have a bad feeling about your current solution.

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

          @GrecKo said in So close, yet so far. Why index in instatiators should be available outside the delegate.:

          what's your higher level goal is?

          I am working on a data driven display. I basically want to keep a list of objects that I can stored as a json string or in a Settings parameter. I intend to build a drag and drop display app that is configurable by the user.

          No, I had not see DelegateChooser. I will look into that. The problem with a loader is that I could not specify the configured properties for each object. With createObject you provide the properties for each instance.

          I finally built something that can be loaded by a Repeater, but provide properties for each object. I plan on generating two types of main objects: RuntimeObject and EditorObject. Both will take the same data. But EditorObject will be able to be dragged around and adjusting size. RuntimeObject will allow some interaction, but no editing. The base object for RuntimeObject is InstanceObject that handles the lifetime of the object. the EditorObject will most likely be based on RuntimeObject so it can do everything it does, plus add editing features.

          The InstanceObject will be what is created by the definition of the object by the properties object.

          C++ is a perfectly valid school of magic.

          1 Reply Last reply
          0
          • GrecKoG GrecKo

            Why not just use a Loader as a component, you could assign it a sourceComponent according to the index.

            Also why do you have such an heterogeneous list?
            Have you looked at DelegateChooser?

            Can you describe us what's your higher level goal is? I have a bad feeling about your current solution.

            fcarneyF Offline
            fcarneyF Offline
            fcarney
            wrote on last edited by
            #5

            @GrecKo said in So close, yet so far. Why index in instatiators should be available outside the delegate.:

            Have you looked at DelegateChooser?

            I think this could work if there was a simple way to set the properties in a javascript object when the delegate is built. I need to push the properties of an js object into the created object. I have written a util function to setProperty/getProperty of any QObject programmatically. This will aid in saving objects after editing. I can parse a list of of properties and save only those properties.

            It amazes me all the qml objects there are that I don't know about. I am always finding new ones that solve specific problems.

            C++ is a perfectly valid school of magic.

            1 Reply Last reply
            0
            • GrecKoG Offline
              GrecKoG Offline
              GrecKo
              Qt Champions 2018
              wrote on last edited by
              #6

              @fcarney said in So close, yet so far. Why index in instatiators should be available outside the delegate.:

              I think this could work if there was a simple way to set the properties in a javascript object when the delegate is built.

              Why?
              The delegate can access the data of your model.

              It can be done with a Loader too.

              I've created something similar to you I believe, a UI editor in QML, with different types possible and forwarded the data to the correct delegate.

              You are doing too much in imperative javascript. Stay declarative.

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

                @GrecKo said in So close, yet so far. Why index in instatiators should be available outside the delegate.:

                You are doing too much in imperative javascript.

                But I need imperative to set the properties on the object. Either I do it in createObject or do it inside the delegate. Right now createObject is cleaner.

                C++ is a perfectly valid school of magic.

                1 Reply Last reply
                0
                • GrecKoG Offline
                  GrecKoG Offline
                  GrecKo
                  Qt Champions 2018
                  wrote on last edited by
                  #8

                  ¿ʕ?
                  By doing it your way, the delegates are not bound to the model data.

                  There's multiple ways to do it declaratively, here's one:

                  import QtQuick 2.15
                  import QtQuick.Window 2.15
                  import QtQuick.Controls 2.15
                  import Qt.labs.qmlmodels 1.0
                  
                  Window {
                      id: root
                      visible: true
                      width: 640
                      height: 480
                      title: qsTr("Hello World")
                  
                      property var elementsModel: [
                          {
                              type: "circle",
                              x: 10,
                              y: 10,
                              width: 20,
                              height: 20,
                              properties: {
                                  color: "blue"
                              }
                          },
                          {
                              type: "button",
                              x: 50,
                              y: 30,
                              width: 200,
                              height: 20,
                              properties: {
                                  text: "push"
                              }
                          }
                      ]
                      Repeater {
                          model: root.elementsModel
                          delegate: DelegateChooser {
                              role: "type"
                              DelegateChoice {
                                  roleValue: "circle"
                                  Rectangle {
                                      x: modelData.x
                                      y: modelData.y
                                      width: modelData.width
                                      height: modelData.height
                                      color: modelData.properties.color
                                      radius: width / 2
                                  }
                              }
                              DelegateChoice {
                                  roleValue: "button"
                                  Button {
                                      x: modelData.x
                                      y: modelData.y
                                      width: modelData.width
                                      height: modelData.height
                                      text: modelData.properties.text
                                  }
                              }
                          }
                      }
                  }
                  
                  
                  1 Reply Last reply
                  1
                  • fcarneyF Offline
                    fcarneyF Offline
                    fcarney
                    wrote on last edited by
                    #9

                    I am struggling to modify the model. Either it won't change, or it does, but it is not notifying of the changes. I tweaked your example to show you what I mean:

                                DelegateChoice {
                                    roleValue: "button"
                                    Button {
                                        x: modelData.x
                                        y: modelData.y
                                        width: modelData.width
                                        height: modelData.height
                                        text: modelData.properties.text
                    
                                        onClicked: {
                                            console.log(modelData.properties.text)
                                            modelData.properties.text = "push again"
                                            console.log(modelData.properties.text)
                    
                                            console.log(elementsModel[index].properties.text)
                                            elementsModel[index].properties.text = "please push"
                                            console.log(elementsModel[index].properties.text)
                                        }
                                    }
                                }
                    

                    C++ is a perfectly valid school of magic.

                    1 Reply Last reply
                    0
                    • GrecKoG Offline
                      GrecKoG Offline
                      GrecKo
                      Qt Champions 2018
                      wrote on last edited by
                      #10

                      That's because it's a plain JS array as a model, it doesn't know it has changed. Use a proper model to do that, or as a workaround call root.elementsModelChanged() or do root.elementsModel = root.elementsModel.

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

                        Yeah, I think I need a list model of json objects. I will store qvariants, but assume they are json objects. I can handle data change by the normal list signals for insert, change, etc. Part of my issue was trying to do the data heavy lifting is js when I should have been using c++.

                        Thanks for your insight @GrecKo! I learned quite a bit from you.

                        C++ is a perfectly valid school of magic.

                        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