Разница между шириной, высотой и неявным Ширина/Высота и соответствующие прецеденты в QML

В чем разница между width/height и implicitWidth/Height в QML? Когда следует устанавливать неявные измерения вместо обычного? Когда следует задавать неявные размеры вместо обычного из компонента/элемента?

Ответ 1

Как правило, использование implicitHeight/Width имеет смысл только в компонентах многократного использования.

Он дает подсказку о натуральном размере предмета без соблюдения этого размера.

В качестве примера возьмем Image. Естественный размер изображения будет отображать один пиксель из файла изображения в один пиксель на экране. Но это позволяет нам растягивать его, поэтому размер не применяется и может быть переопределен.

Скажем сейчас, мы хотим иметь галерею с изображениями неизвестного измерения, и мы не хотим расти, а только при необходимости сокращаем их. Поэтому нам нужно сохранить естественный размер изображения. То есть, когда подразумеваемая высота вступает в игру.

Image {
    width: Math.max(150, implicitWidth)
    height: Math.max(150, implicitHeight)
}

В пользовательских компонентах у вас есть выбор, как определить размеры.

Один из вариантов состоит в том, чтобы иметь все размеры относительно компонентов root -node, может быть, вот так:

Item {
    id: root
    Rectangle {
        width: root.width * 0.2
        height: root.height * 0.2
        color: 'red'
    }
    Rectangle {
        x: 0.2 * root.width
        y: 0.2 * root.height
        width: root.width * 0.8
        height: root.height * 0.8
        color: 'green'
    }
}

В этом случае нет естественного размера объекта. Все отлично работает для каждого размера, заданного для компонента.

С другой стороны, у вас может быть объект, который имеет естественный размер - это происходит, например, если у вас есть абсолютные значения в нем

Item {
    id: root
    property alias model: repeater.model
    Repeater {
        id: repeater
        delegate: Rectangle {
            width: 100
            height: 100
            x: 102 * index
            y: 102 * index
        }
    }
}

В этом примере вы должны предоставить пользователю информацию о натуральном размере, в котором контент не защищает элемент. Пользователь может все же решить установить меньший размер и иметь дело с выступом, например, отсекая его, но ему нужна информация о натуральном размере, чтобы принять его решение.

Во многих случаях childrenRect.height/width является хорошей мерой для implcitHeight/Width, но есть примеры, где это не очень хорошая идея. - например, когда содержимое элемента имеет x: -500.

Пример реальной жизни - это Flickable, специально предназначенный для хранения больших объектов, чем его собственный размер. Имея размер Flickable чтобы быть равным содержанию, не было бы естественным.

Также будьте осторожны при использовании scale в пользовательских компонентах, поскольку childRect не будет знать о масштабировании.

Item {
    id: root
    implicitWidth: child.width * child.scale
    implicitHeight: child.height * child.scale
    Rectangle {
        id: child
        width: 100
        height: 100
        scale: 3
        color: 'red'
    }
}

И к вашему комментарию: я просто не понимаю, почему лучше установить implicitWidth/Height вместо установки ширины/высоты корневого размера компонента.

implicitWidht/Height не являются необходимыми - QtQuick может обойтись без них. Они существуют для удобства и должны быть условными.


Практическое правило

Если вы хотите установить размер корневого узла повторно используемого компонента, установите значение implicitWidth/Height.
В некоторых случаях установите его для non-root -node s, если узлы отображаются как свойство.
Сделайте это только, если у вас есть причина для этого (многие официальные компоненты приходят без каких-либо).
Когда вы используете компонент, задайте width/height.

Ответ 2

У меня нет окончательного ответа, но я могу рассказать вам, что я узнал. Во-первых, из документации:

implicitWidth: real

Определяет естественную ширину или высоту элемента, если не задана ширина или высота.

Неявный размер по умолчанию для большинства элементов равен 0x0, однако некоторые элементы имеют неотъемлемый неявный размер, который нельзя переопределить, например, Image и Text.

но менее информативный для ширины:

ширина

Определяет позицию и размер позиции.

width и height отражают фактический размер элемента в сцене. Неявный размер является своего рода неотъемлемым свойством самого элемента. 1

Я использую их следующим образом: Когда я создаю новый элемент и его можно изменить, я устанавливаю неявный размер внутри объекта 2. Когда я использую объект, я часто устанавливаю реальный размер явно извне.

Неявный размер объекта можно переопределить, установив высоту и ширину.

пример: TextWithBackground.qml

Item {
    implicitWidth: text.implicitWidth
    implicitHeight: text.implicitHeight
    // the rectangle will expand to the real size of the item
    Rectangle { anchors.fill: parent; color: "yellow" }
    Text { id: text; text: "Lorem ipsum dolor..." }
}

пример: MyWindow.qml

Item {
    width: 400
    height: 300
    TextWithBackground {
         // half of the scene, but never smaller than its implicitWidth
         width: Math.max(parent.width / 2, implicitWidth)
         // the height of the element is equal to implicitHeight
         // because height is not explicitly set
    }
}

1) Для некоторых элементов, таких как Text, неявная высота зависит от (неявной) ширины.
2) Неявный размер обычно зависит от неявного размера его детей.