writing a layout in QML
when this happens, the first instinct is to fall into despair - but there's really no need for that. writing your own layout really isn't that hard. Here's a small, fairly self contained example doing just that.
MyLayout.qml:
import QtQuick 2.0
Item {
id: layout
property bool ready: false
onChildrenChanged: performLayout()
onWidthChanged: performLayout()
onHeightChanged: performLayout()
/* the meat of the layout */
function performLayout() {
/* nothing to layout? don't bother then */
if (layout.children.length == 0)
return
var currentX = 0
console.log("DOING LAYOUT FOR " + layout.children.length + " ITEMS")
/* first real step of doing anything: go over all the children */
for (var i = 0; i < layout.children.length; ++i) {
var obj = layout.children[i]
/* in the real world, we'd probably do something a lot more complex,
* but let's just position our children along a row.
*/
console.log("Positioning at " + currentX + " to " + (currentX + obj.width))
obj.x = currentX
currentX += obj.width
}
console.log("LAYOUT DONE")
}
}
MyItem.qml:
import QtQuick 2.0
Rectangle {
width: 100
height: 50
color: "black"
Rectangle {
width: 90
height: 40
anchors.centerIn: parent
color: "red"
}
}
main.qml
import QtQuick 2.0
Rectangle {
width: 1000
height: 100
MyLayout {
MyItem { }
MyItem { }
MyItem { }
MyItem { }
MyItem { }
MyItem { }
MyItem { }
}
}
This is obviously very simplified for demonstration purposes, to name a few things that it doesn't do:
- it omits things like margins, wrapping
- it will break if MyItem is ever anchored
- it doesn't use anchoring (which might make for a more optimal implementation in this particular case - at the least, it wouldn't have to relayout if the width/height of the layout changed)
- it doesn't relayout if the geometry of the children change
- it relayouts whenever properties changes, which isn't optimal if e.g. the layout is animating a change, instead, it should delay a relayout using a Timer
All of these are left to the reader, but hopefully it's of some help in getting started.