верхний / нижний предел с компонентами высоты заполнения

#qt #qml

#qt #qml

Вопрос:

Я столкнулся с проблемой, касающейся верхнего / нижнего поля для компонентов внутри макета (здесь GridLayout, но, похоже, это то же самое с ColumnLayout) с fillHeight .

Рассматривая следующий пример:

`

 import QtQuick 2.0
import QtQuick.Layouts 1.2

Item {
    width : 800
    height : 480
    GridLayout {
        anchors.fill: parent
        columns: 2
        rows : 2
        Rectangle {
            color:"red"
            Layout.fillHeight: true
            width : 400
        }
        Rectangle {
            color:"green"
            Layout.rowSpan: 2
            Layout.fillHeight: true
            width : 400
        }
        Rectangle {
            color:"blue"
            Layout.fillHeight: true
            width : 400
            Layout.bottomMargin: 10
        }
    }
}
  

`
Отображение выглядит следующим WithBottom.jpgобразом .

Просто прокомментировав строку «Layout.bottomMargin: 10», восстановите соотношение между красными и синими прямоугольниками:

WithoutBottom.jpg

Похоже, что рассчитывается соотношение, учитывающее поля, когда я предполагаю, что этого не должно быть. Действительно, высота синего прямоугольника, по-видимому, равна (верхнее нижнее поля) * высоте красного (я тестировал примерно с дюжиной значений, возможно, недостаточно).

Ответ №1:

Механизм компоновки действительно использует implicitHeight для вычисления результирующих размеров. Поскольку значение implicitHeight прямоугольника равно 0, синий прямоугольник будет в 10 раз больше красного. Вы можете немного поиграть с настройками implicitHeight на прямоугольниках:

 Item {
    width : 800
    height : 480
    GridLayout {
        anchors.fill: parent
        columns: 2
        rows : 2
        Rectangle {
            color:"red"
            Layout.fillHeight: true
            implicitHeight: 200
            width : 400
            onHeightChanged: console.log("red", height)
        }
        Rectangle {
            color:"green"
            Layout.rowSpan: 2
            Layout.fillHeight: true
            width : 400
        }
        Rectangle {
            color:"blue"
            implicitHeight: 200
            Layout.fillHeight: true
            width : 400
            Layout.bottomMargin: 10
            onHeightChanged: console.log("blue", height)
        }
    }
}
  

Однако это похоже на грязное решение. Результирующий размер зависит от implicitHeight набора, но не полностью. По сути, вы изменяете «вес» нижнего предела при вычислении механизма компоновки.

Чтобы создать решение без загрязнения, вы можете поместить синий прямоугольник внутри элемента и привязать к нему синий прямоугольник с нижним краем. (таким образом, в элементе нет Layout.bottomMargin). Но это немного зависит от вашего желаемого конечного результата, так как синий прямоугольник будет меньше красного.

Ответ №2:

Спасибо за ответ!

Да, для меня это определенно грязное решение для установки implicitHeight, и я не могу применить его к своему приложению.

Другое решение почти похоже на то, о котором я думал. Разница в том, что я помещаю ColumnLayout, который заполняет его родительский элемент (с интервалом строк: 2) и содержит как красные, так и синие прямоугольники, и в котором я запрашиваю Layout.bottomPadding . И таким образом это работает.

Это всего лишь обходной путь, который работает для того, что я хочу сделать, но при этом невозможно установить topMargin на синем прямоугольнике без использования интервала. Но, как я уже сказал, для меня это нормально.

поскольку синий прямоугольник будет меньше красного

Да, я знаю об этом, и это то, чего я ожидаю. И в моем решении также есть эта разница в высоте.

Редактировать: нет, я полностью ошибаюсь в этом последнем пункте, и на самом деле, с ColumnLayout красный и синий будут одинакового размера: с макетом