将组件width
或height
设置为零与将visible
属性设置为false
的效果相同吗?
示例用例:
我有一个项目,它滑入窗口。通过将其高度从0
设置为x
以及当我将此项目从x
关闭到0
时,会发生滑动。不想深入了解为什么我没有动画项目的位置。当项目的高度为0时,我应该将其visible
属性设置为false
还是它没有任何区别?
答案 0 :(得分:5)
不是真的,除非你剪辑。最好尽可能避免剪裁。
大小为零的Item
仍会显示其子项。
而将visible设置为false将隐藏整个对象树。
在您的特定情况下,似乎无关紧要,只要它不会导致您有不必要的可见剩菜。你当然不希望有visible: height
这样的绑定,因为它会在动画的每一步都不必要地执行。
为了安全起见,您可以在动画上安装处理程序以切换可见性:
// in the animation
onStarted: if (!item.height) item.visible = true // show if start at 0
onStopped: if (!item.height) item.visible = false // hide if end at 0
如果您直接将可见性绑定到高度,这将避免您获得的连续重新评估,但仍会确保在对象开始展开之前的可见性,并在完成签约后关闭。
答案 1 :(得分:2)
正如 dtech 已经指出的那样,组件的根节点的维度不会自动表示基础对象树的维度。举个例子吧:
Item {
id: root
Text {
id: txt
text: 'some text produces implicit width'
}
}
在此示例中,将显示txt
的文字,但root
的尺寸为width: 0; height: 0
。
正如已经提到的 dtech ,您可以将clip
设置为true
,但这不可取,因为它会传递给呈现器,呈现{{1}和它的树,最后应用剪辑 - 单独批处理。
如果你有类似的东西:
Item
渲染器在渲染时不会做任何额外的操作,因为它可以在与其余渲染器相同的批处理中进行处理。但是,作为开发人员,很难说,当大小设置为Item {
Rectangle {
anchors.fill: parent
color: 'red'
}
}
时,是否可以看到某些内容。因此,始终可以正确设置0
。
我们可能只是设置
visible
只要我们不在任何属性上制作动画或经常更改它们,就可以正常工作。至少对于动画我们可能有很好的知识,当任何这些属性可能成为visible: width > 0 && height > 0 && opacity > 0
并使用此信息来减少评估量。
关于QML的好处是,逻辑表达式是从左到右计算的,这意味着在我们的上一个例子中:
0
和width === 0
发生变化,则不会触发重新评估height
和height === 0
发生变化,则每次更改都会触发重新评估。这意味着,我们需要先把最稳定的条件。这可能是我们的有关何时可能更改任何值的信息。在动画运行时,我建议使用width
属性来阻止重新评估绑定。
我们来看一个更完整的例子:点击后,这个animation.running
会从Rectangle
缩小到width: 800
- 这会将其设置为不可见。
或者三个附加属性width: 0
绑定到表达式,我们可以使用它们来设置binding1, binding2, binding3
。当重新绑定特定部分的绑定时,我们会记录下来。
visible
正如我们所看到的,当宽度发生变化时,Rectangle {
id: rect
color: 'red'
width: 800
height: 600
NumberAnimation {
id: ani1
target: rect
property: 'width'
from: 800
to: 0
duration: 3000
}
}
MouseArea {
anchors.fill: parent
onClicked: ani1.running = true
}
property bool binding1: {console.log("1", !rect.width); return !rect.width}
property bool binding2: {!ani1.running && (function() { console.log("2", !rect.width); return !rect.width })()}
property bool binding3: {(function() { console.log("3", !rect.width); return !rect.width })() && !ani1.running}
// equivalent, stripped of the logging:
// property bool binding1: !rect.width
// property bool binding2: !ani1.running && !rect.width
// property bool binding3: !rect.width && !ani1.running
会不断被重新评估。这是不可取的
我们可以看到,binding1
仅在创建时评估一次,并且只要binding2
停止运行
在ani
中我们反过来了,我们首先评估binding3
,然后评估width
是否正在运行。这意味着,只要ani
发生变化,我们就会重新评估。
我们也可以使用信号处理程序width
和ani.onStarted
然后显式设置visiblity,但这不会是声明,QML鼓励你总是努力保持declarativ。