I really like QML. I like how I can define components (comparable to classes) and their properties, and instantiate them from somewhere else (comparable to objects).
I can define, let's say, a button, having some look and feel, and a label text on it. This could be done, for example, using this component definition (Button.qml
):
Item { id: button property string label anchors.fill: parent Rectangle { anchors.fill: parent radius: 10 color: "gray" Text { anchors.centerIn: parent font.pixelSize: 20 text: button.label color: "white" } } }
and instanciated in this main file (main.qml
):
Rectangle { width: 300 height: 200 Button { anchors.centerIn: parent anchors.margins: 50 label: "Hello button!" } }
But I see the following restriction: I can only define a button template with some properties, not with some placeholder. All children defined in the instance will be direct children, at least per default, and I want to change this behavior.
Let's say I want to place an item (let's say an image, but I don't want to tell the definition of Button
that it will be an image) in the button. I imagine something like this:
Item { id: button property Item contents <-- the client can set the placeholder content here anchors.fill: parent Rectangle { anchors.fill: parent radius: 10 color: "gray" Item { id: placeholder <-- where the placeholder should be inserted } } Component.onCompleted: { // move the contents into the placeholder... } }
How can I achieve this? I don't know if using Component.onCompleted
is the correct way. Note that, however, that in my case the contents will never change afterwards (at least in my current design of the application...).
Also, I want anchoring to work within the placeholder. For example, if I define the contents to be a Text element, being centered in its parent (which will first be the template itself). Then my code moves this Text instance into the placeholder and the parent anchors should then be those of the placeholder item, not the template item.
I found a much nicer answer to this question, suggested in a presentation of the Qt Developer Days 2011 "Qt Quick Best Practices and Design Patterns".
They use default property alias ...
to alias the child items to any property of any item. If you don't want to alias the children but give the alias property a name, just remove default
. (Literal children are per QML definition the value of the default property.)
Item { id: button default property alias contents: placeholder.children anchors.fill: parent Rectangle { anchors.fill: parent radius: 10 color: "gray" Item { id: placeholder <-- where the placeholder should be inserted } } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With