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. Use a custom item as a children declared as a property (like delegate in views)
Qt 6.11 is out! See what's new in the release blog

Use a custom item as a children declared as a property (like delegate in views)

Scheduled Pinned Locked Moved Solved QML and Qt Quick
4 Posts 3 Posters 3.8k Views 1 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.
  • M Offline
    M Offline
    MoaMoaK
    wrote on last edited by
    #1

    I'm trying to create an object where you can declare a custom item that will be inserted in my custom object. But I don't know how to use this delegate later in my code.
    Example:

    // MyObject.qml
    Row {
        property var customItem
        ItemBefore { }
        // This where I don't know how to use the custom item
        customItem {
            // That would be even better if I could set properties 
            // that are used by the item (width, height, ...)
            // like with a regular QML object
            someProperties: true
        }
        ItemAfter { }
    }
    
    // Main.qml
    Item {
        MyObject {
            customItem: Rectangle { color: "#FF0000" }
        }
        MyObject {
            customItem: Rectangle { color: "#00FF00" }
        }
        MyObject {
            customItem: Rectangle { color: "#0000FF" }
        }
    }
    

    The behavior I'm looking for is similar to the one used by ListView and GridView with the delegate property.
    Can anyone help me ?
    MoaMoaK

    DuBuD 1 Reply Last reply
    0
    • PhrogzP Offline
      PhrogzP Offline
      Phrogz
      wrote on last edited by Phrogz
      #2

      The easiest way I can think to do this in pure QML is use a Repeater instead of your custom object. It takes a delegate but does not impose any particular layout. You can let the items position themselves (e.g. using x/y properties in the delegate based on the model) or you can control their layout yourself by using the itemAdded signal and adjusting properties of the item there.

      But assuming that does not meet your needs, and since it does not answer your question, I would wrap your delegate in a Component so that you can easily instantiate it using createObject():

      main.qml

      import QtQuick 2.6
      import QtQuick.Window 2.2
      Window {
          visible:true; width:640; height:480; title:"Replicator"
          Replicator {
              copies: 15
              Component {
                  Rectangle {
                      width:200; height:100
                      color:Qt.rgba(255,0,0,0.2); border.color:'red'
                      property alias label: t.text
                      Text { id:t; anchors.centerIn:parent }
                  }
              }
          }
      }
      

      Replicator.qml

      import QtQuick 2.0
      Item {
          id: root
          anchors.fill: parent
          property int copies: 5
          default property var template
          Component.onCompleted: {
              for (var i=copies;i--;) {
                  var props = {
                      label: "I'm item #"+i,
                      x: Math.random()*root.width/2,
                      y: Math.random()*root.height/2
                  };
                  template.createObject(root, props);
              }
          }
      }
      

      This produces a result like:
      0_1510358350481_Screen Shot 2017-11-10 at 4.58.29 PM.png

      In the example above I've used the default keyword to allow your delegate without a label. This is purely optional.

      There may be a way to do this without a Component, but I don't know what it is. The page on Dynamic QML Object Creation says:

      There are two ways to create objects dynamically from JavaScript. You can either call Qt.createComponent() to dynamically create a Component object, or use Qt.createQmlObject() to create an object from a string of QML.

      You don't have a string of QML, and so you must use a component.

      A true delegate object like ListView and Repeater accept would require some way to derive a component from an instance, and that does not appear to me to be possible in pure QML.

      1 Reply Last reply
      0
      • M MoaMoaK

        I'm trying to create an object where you can declare a custom item that will be inserted in my custom object. But I don't know how to use this delegate later in my code.
        Example:

        // MyObject.qml
        Row {
            property var customItem
            ItemBefore { }
            // This where I don't know how to use the custom item
            customItem {
                // That would be even better if I could set properties 
                // that are used by the item (width, height, ...)
                // like with a regular QML object
                someProperties: true
            }
            ItemAfter { }
        }
        
        // Main.qml
        Item {
            MyObject {
                customItem: Rectangle { color: "#FF0000" }
            }
            MyObject {
                customItem: Rectangle { color: "#00FF00" }
            }
            MyObject {
                customItem: Rectangle { color: "#0000FF" }
            }
        }
        

        The behavior I'm looking for is similar to the one used by ListView and GridView with the delegate property.
        Can anyone help me ?
        MoaMoaK

        DuBuD Offline
        DuBuD Offline
        DuBu
        wrote on last edited by
        #3

        @MoaMoaK Using a Loader should perfectly do want you want to achieve:

        // MyObject.qml
        Row {
            property alias customItem: loader.sourceComponent
            ItemBefore { }
            Loader {
              id: loader
              // Just a bunch of custom properties
              property int widthOfCustomItem: 100
              property int heightOfCustomItem: 100
            }
            ItemAfter { }
        }
        
        // Main.qml
        Item {
            MyObject {
                customItem: Rectangle {
                  color: "#FF0000"
                  // You can use all properties of the Loader inside your customItem
                  width: widthOfCustomItem
                  height: heightOfCustomItem
                }
            }
            MyObject {
                customItem: Rectangle { color: "#00FF00" }
            }
            MyObject {
                customItem: Rectangle { color: "#0000FF" }
            }
        }
        
        M 1 Reply Last reply
        2
        • DuBuD DuBu

          @MoaMoaK Using a Loader should perfectly do want you want to achieve:

          // MyObject.qml
          Row {
              property alias customItem: loader.sourceComponent
              ItemBefore { }
              Loader {
                id: loader
                // Just a bunch of custom properties
                property int widthOfCustomItem: 100
                property int heightOfCustomItem: 100
              }
              ItemAfter { }
          }
          
          // Main.qml
          Item {
              MyObject {
                  customItem: Rectangle {
                    color: "#FF0000"
                    // You can use all properties of the Loader inside your customItem
                    width: widthOfCustomItem
                    height: heightOfCustomItem
                  }
              }
              MyObject {
                  customItem: Rectangle { color: "#00FF00" }
              }
              MyObject {
                  customItem: Rectangle { color: "#0000FF" }
              }
          }
          
          M Offline
          M Offline
          MoaMoaK
          wrote on last edited by
          #4

          @DuBu Sorry I'm a bit late, but really using Loader was THE solution I wanted, thx a lot.
          It works perfectly.

          1 Reply Last reply
          1

          • Login

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