宽度,高度和implicitWidth / Height之间的差异以及QML中的相应用例

时间:2017-08-29 19:18:54

标签: qt qml

QML中width/heightimplicitWidth/Height之间有什么区别?应该何时设置隐式维度而不是常规维度?何时应该从组件/项目中询问隐式维度而不是常规维度?

3 个答案:

答案 0 :(得分:10)

通常,implicitHeight/Width的使用仅在可重用组件中有意义。

它提供了项目自然大小的提示,但不强制执行此大小。

我们以Image为例。图像的自然尺寸将图像文件中的一个像素映射到屏幕上的一个像素。但它允许我们拉伸它,因此不会强制执行大小并且可以覆盖它。

现在让我们说,我们希望有一个展示未知维度图片的图库,我们不希望增长,但只在必要时缩小它们。所以我们需要存储图像的自然尺寸。也就是说,隐含高度发挥作用。

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

在自定义组件中,您可以选择如何定义尺寸。

唯一的选择是拥有相对于组件root - 节点的所有维度,可能是这样的:

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/widthimplcitHeight/Width的一个很好的衡量标准,但也有一些例子,这不是一个好主意。 - 例如当项目的内容有x: -500时。

真实例子是Flickable,它专门用于包含比自己大小更大的对象。将Flickable的大小等于内容是不自然的。

在自定义组件中使用scale时也要小心,因为childrenRect不会知道缩放。

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   在某些情况下,如果节点作为属性公开,则将其设置为非根节点   只有这样,如果你有理由(许多官方组件没有任何原因)   使用组件时,请设置width/height

答案 1 :(得分:5)

我没有明确的答案,但我可以告诉你我发现了什么。首先,from the documentation

  

implicitWidth:real

     

如果没有宽度或高度,则定义Item的自然宽度或高度   已指定。

     

大多数项目的默认隐式大小为0x0,但有些项目   有一个固有的隐含大小,不能被覆盖,因为   例如,ImageText

但是less informative for width

  

宽度

     

定义项目的位置和大小。

widthheight反映了场景中项目的实际大小。隐含大小是项目本身的某种固有属性。 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)隐式大小通常取决于其子级的隐式大小。

答案 2 :(得分:1)

当根据项目的内容计算项目的大小时,应该使用隐式大小。尽管在父项上设置widthheight可能会影响其子项的大小,但在设置隐式大小时绝对不应该这样。

经验法则

  

内向型尺寸只能“冒泡”,即儿童不应该   查找其父级的隐式大小以计算自己的父级   隐式大小,任何父母都不应尝试强制其隐式大小   孩子们。

如果您尝试在类似于布局的组件上设置width,则最初会根据其子项的width(而不是implicitWidth)来计算其宽度,并且该子项受父母的大小影响,您最终会遇到绑定循环。

这就是为什么存在该属性的原因-在根据其内容计算项目的大小时打破循环依赖性。