Reputation: 2713
I have a ColumnLayout
, which has its anchor set to anchor.fill: parent
, therefore it has already a set dimension, which depends on its parent dimension.
How can I add Rectangles
into this ColumnLayout
, with a specific spacing from top to bottom?
Right now I have this:
ColumnLayout {
anchors.fill: parent
spacing: 2
Rectangle {
height: 50
width: 50
color: "red"
}
Rectangle {
height: 50
width: 50
color: "green"
}
Rectangle {
height: 50
width: 50
color: "blue"
}
}
But instead of having the rectangles from top to bottom with a spacing 2
it layouts the Rectangle
s evenly in the ColumnLayout
.
One solution would be to anchor the first rectangle to the parent's top and the anchor the rest of the rectangles one after the other, but I would like to avoid this if possible.
Upvotes: 7
Views: 23223
Reputation: 7692
Differently from previous positioners, such as Column
or Row
, layouts were introduced to support graphical scaling of UI, also by filling available space (in this specific case fill their parent). In that sense the spacing
property should not be seen as a strict upper bound to the spacing between Item
s but as the minimum allowed distance between them.
The current approach to solve your issue is to use a "filler" Item
, which uses the fillHeight
property. This Item
occupies all the space left by the other Item
s inside the layout thus packing them together, as needed:
import QtQuick 2.5
import QtQuick.Window 2.2
Window {
visible: true
width: 100
height: 200
ColumnLayout {
anchors.fill: parent
spacing: 2
Rectangle {
height: 50
width: 50
color: "red"
}
Rectangle {
height: 50
width: 50
color: "green"
}
Rectangle {
height: 50
width: 50
color: "blue"
}
Item { Layout.fillHeight: true } // <-- filler here
}
}
Note that you can exploit the same approach and add a filler at the beginning of the layout to vertically center the children Item
s. Finally, note that in this case it would be advisable to use a Column
which lays down the Item
s correctly as expected, disregarding the available space left.
Just make your choice.
It should be noted that while this approach works Layout
s provide a lot of properties to control the size of the Item
s. Please refer to the other answer for some insight on the subject.
Upvotes: 18
Reputation: 3030
The accepted answer is one valid approach, however, there are others.
ColumnLayout
decides its own heightIf you are simply trying to place items in a column from the top downwards, then there is no need to force the height of the ColumnLayout
.
Instead of
anchors.fill: parent
use
width: parent.width
and let the ColumnLayout size itself to fit its contents, as below:
import QtQuick 2.0
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0
ApplicationWindow {
visible: true
width: 100
height: 200
ColumnLayout {
width: parent.width
spacing: 2
Rectangle {
height: 50
width: 50
color: "red"
}
Rectangle {
height: 50
width: 50
color: "green"
}
Rectangle {
height: 50
width: 50
color: "blue"
}
}
}
If there are too many or too few items to perfectly fill the layout, you can allow the layout to resize the items (instead of resizing the spacing).
The following attached properties control how the layout treats your items, when deciding what can be stretched or shrunk in order to fit the layout:
Layout.preferredHeight
Layout.minimumHeight
Layout.maximumHeight
Layout.fillHeight
Example, where Rectangle
s are enlarged slightly to achieve the desired spacing:
import QtQuick 2.0
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0
ApplicationWindow {
visible: true
width: 100
height: 200
ColumnLayout {
anchors.fill: parent
spacing: 2
Rectangle {
Layout.fillHeight: true
Layout.preferredHeight: 50
width: 50
color: "red"
}
Rectangle {
Layout.fillHeight: true
Layout.preferredHeight: 50
width: 50
color: "green"
}
Rectangle {
Layout.fillHeight: true
Layout.preferredHeight: 50
width: 50
color: "blue"
}
}
}
Upvotes: 7