Use a custom item as a children declared as a property (like delegate in views)
-
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
ListViewandGridViewwith thedelegateproperty.
Can anyone help me ?
MoaMoaK -
The easiest way I can think to do this in pure QML is use a
Repeaterinstead 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 theitemAddedsignal and adjusting properties of theitemthere.But assuming that does not meet your needs, and since it does not answer your question, I would wrap your delegate in a
Componentso that you can easily instantiate it usingcreateObject():main.qmlimport 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.qmlimport 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:

In the example above I've used the
defaultkeyword 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 useQt.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.
-
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
ListViewandGridViewwith thedelegateproperty.
Can anyone help me ?
MoaMoaK@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" } } } -
@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" } } }