Как создать многоуровневую компоновку жидкости в QML
Я разработал макет в QML, чтобы узнать больше о его функциях и задать несколько вопросов о "лучших практиках" при разработке такого макета. Вот это:
Это по сути ColumnLayout состояла из трех RowLayouts, каждый с некоторыми прямоугольникs. Размер каждой строки и прямоугольника должен быть вычислен, например:
- первая строка: высота = 40%, ширина = Сто%
- красный прямоугольник, заполняющий всю область
- второй ряд: высота = 20%, ширина = 100%
- темно-зеленый прямоугольник: высота = 100%, ширина = 20%,
- светло-зеленый прямоугольник: высота = 100%, ширина = 80%
- третий ряд: высота = 40%, ширина = 100%
- темно-синий прямоугольник: высота = 100%, ширина = 40%,
- Синий Прямоугольник: Высота = 100%, Ширина = 20%
- светло-голубой прямоугольник: высота = 100%, ширина = 40%
QML, который я придумал, работает и находится в следующем. У меня есть несколько вопросов по этому поводу:
- я установил процент ширины и высоты, используя макет.preferredHeight: X * родитель.высота узор. Другие опции вызвали некоторые проблемы (например, preferredHeight вызвал предупреждения цикла привязки). Мой верный подход и эффективно?
- как хак, я установил макет.fillWidth: true для первого элемента строки #2 и строки #3, что для меня не имеет смысла, но работает. Если я установлю их ширину в процентах (например,макет.preferredWidth: 0.2*родитель.ширина) их строка свернется до ширины 0. Это ожидаемое поведение? Есть ли лучшее решение?
- у вас есть какие-либо рекомендации на макеты? Я на правильном пути?
вот мой Код QML для макета:
ApplicationWindow {
x: 500
y: 100
width: 250
height: 150
visible: true
ColumnLayout {
anchors.fill: parent
spacing: 0
RowLayout {
spacing: 0
Layout.preferredHeight: 0.4*parent.height
Layout.fillHeight: false
Rectangle {
Layout.fillHeight: true
Layout.fillWidth: true
color: "red"
}
}
RowLayout {
spacing: 0
Layout.preferredHeight: 0.2*parent.height
Layout.fillHeight: false
Rectangle {
Layout.fillHeight: true
Layout.fillWidth: true
color: "darkGreen"
}
Rectangle {
Layout.fillHeight: true
Layout.preferredWidth: 0.8*parent.width
color: "lightGreen"
}
}
RowLayout {
spacing: 0
Layout.preferredHeight: 0.4*parent.height
Layout.fillHeight: false
Rectangle {
Layout.fillHeight: true
Layout.fillWidth: true
color: "darkBlue"
}
Rectangle {
Layout.fillHeight: true
Layout.preferredWidth: 0.2*parent.width
color: "blue"
}
Rectangle {
Layout.fillHeight: true
Layout.preferredWidth: 0.4*parent.width
color: "lightBlue"
}
}
}
}
обновление:
мой подход кажется более хакерским, чем я ожидал:
- положить текст элементов, так как дети в этом макете поднимает привязка цикла предупреждения типа:
QML QQuickLayoutAttached: обнаружен цикл привязки для свойства "preferredWidth"
если текст обертки внутри прямоугольник предупреждения исчезнуть.
- на интервал: 0 кажется, играет важную роль. Опущение этого вызовет предупреждения цикла привязки.
хотя мой подход к дизайну компоновки fluid в QML работает, он имеет некоторые серьезные проблемы и может не подпадать под "лучшие практики".
2 ответов
наш QtQuick.Макет не дает никаких реальных улучшений по сравнению с классической системой крепления. Я бы рекомендовал избегать их. Вы можете иметь больше контроля над своим макетом, используя якоря.
вот тот же самый дизайн без QtQuick.Макет:
ApplicationWindow {
x: 500
y: 100
width: 250
height: 150
visible: true
Column {
anchors.fill: parent
Row {
anchors.left: parent.left
anchors.right: parent.right
height: 0.4 * parent.height
Rectangle {
anchors.top: parent.top
anchors.bottom: parent.bottom
width: parent.width
color: "red"
}
}
Row {
anchors.left: parent.left
anchors.right: parent.right
height: 0.2 * parent.height
Rectangle {
anchors.top: parent.top
anchors.bottom: parent.bottom
width: 0.2 * parent.width
color: "darkGreen"
}
Rectangle {
anchors.top: parent.top
anchors.bottom: parent.bottom
width: 0.8 * parent.width
color: "lightGreen"
}
}
Row {
anchors.left: parent.left
anchors.right: parent.right
height: 0.4 * parent.height
Rectangle {
anchors.top: parent.top
anchors.bottom: parent.bottom
width: 0.4 * parent.width
color: "darkBlue"
}
Rectangle {
anchors.top: parent.top
anchors.bottom: parent.bottom
width: 0.2 * parent.width
color: "blue"
}
Rectangle {
anchors.top: parent.top
anchors.bottom: parent.bottom
width: 0.4 * parent.width
color: "lightBlue"
}
}
}
}
до сих пор я никогда не встречал никакого дизайна, который невозможно было бы сделать без QtQuick.Макет.
запрещено (и ненужно) пытаться ссылаться на ширину и высоту родителя из элементов внутри макета.
, когда fillWidth
(или fillHeight
) установлено значение true
, то элементы выделяются пространство пропорционально их указанным preferredWidth
(или preferredHeight
).
поэтому правильный способ создания макета заключается в следующем. Я изменил внешний вид только для того, чтобы показать, что интервал и Text
смогите также быть установлено свободно как пожелано. Без привязки петли.
ApplicationWindow {
x: 500
y: 100
width: 250
height: 150
visible: true
ColumnLayout {
anchors.fill: parent
spacing: 5
RowLayout {
spacing: 5
Layout.preferredHeight: 40
Layout.fillHeight: true
Rectangle {
Layout.fillHeight: true
Layout.fillWidth: true
color: "red"
}
}
RowLayout {
spacing: 5
Layout.preferredHeight: 20
Layout.fillHeight: true
Rectangle {
Layout.fillHeight: true
Layout.preferredWidth: 20
Layout.fillWidth: true
color: "darkGreen"
}
Rectangle {
Layout.fillHeight: true
Layout.preferredWidth: 80
Layout.fillWidth: true
color: "lightGreen"
}
}
RowLayout {
spacing: 5
Layout.preferredHeight: 40
Layout.fillHeight: true
Text {
Layout.fillHeight: true
Layout.preferredWidth: 40
Layout.fillWidth: true
color: "darkBlue"
text: "hello world!"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
Rectangle {
Layout.fillHeight: true
Layout.preferredWidth: 20
Layout.fillWidth: true
color: "blue"
}
Rectangle {
Layout.fillHeight: true
Layout.preferredWidth: 40
Layout.fillWidth: true
color: "lightBlue"
}
}
}
}