如何使 QML 动画仅在属性值增加而不是减少时才起作用?
Posted
技术标签:
【中文标题】如何使 QML 动画仅在属性值增加而不是减少时才起作用?【英文标题】:How to make a QML animation work only when a property value is increasing not decreasing? 【发布时间】:2021-06-08 17:52:01 【问题描述】:从Qt官方文档here我了解到我可以为QML项目的x
坐标的变化设置动画。
以下工作,但问题是我希望在 x
的值递减时不激活动画:
Rectangle
id: some_item
x: somePropertyValueThatKeepsChanging
Behavior on x
NumberAnimation
duration: 50
问题:
如何使动画Behavior on x
仅在x
增加时执行,而不是在减少时执行?
我使用的是Qt商业版5.15.1。
【问题讨论】:
可能启用的属性:Behavior on x enabled: x > 0 NumberAnimation duration: 50
【参考方案1】:
这可以通过使用行为的targetValue
(5.12 中添加)和targetProperty
(5.15 中添加)来实现:
Behavior on x
enabled: targetValue > targetProperty.object[targetProperty.name]
NumberAnimation duration: 200
(请注意,您可以只使用targetValue > some_item.x
而不是使用targetProperty
,但targetProperty
允许您定义通用的可重用行为)
小例子:
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15
Window
width: 640
height: 480
visible: true
title: qsTr("Hello World")
Rectangle
id: some_item
x: 0
y: 100
height: 100
width: 100
color: "salmon"
Behavior on x
enabled: targetValue > targetProperty.object[targetProperty.name]
NumberAnimation duration: 200
Row
Button
text: "increase"
onClicked: some_item.x += 10
Button
text: "decrease"
onClicked: some_item.x -= 10
【讨论】:
【参考方案2】:这是可能的,但我不认为这是 QML 行为/动画的内置功能,因此需要一些自定义实现。
而不是将x
直接绑定到变化的值,使用中间监听器来确定新值是大于还是小于当前x
值,并在Behavior
之前设置enabled
标志设置x
。这是一个完整的工作示例:
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
Window
id: root
width: 640
height: 480
visible: true
property real somePropertyThatChanges // simulated externally changing value using timer below
Timer
interval: 500
running: true
repeat: true
onTriggered:
somePropertyThatChanges = Math.round(Math.random()* rect.parent.height) // simulate value changes every 500ms
Rectangle
id: rect
color: "lightgrey"
width: 50
height: 50
property real intermediateValueChecker: root.somePropertyThatChanges
onIntermediateValueCheckerChanged:
if (root.somePropertyThatChanges > rect.x) // check if new value is greater or less than current x, set behavior.enabled accordingly
xBehavior.enabled = true
else
xBehavior.enabled = false
rect.x = somePropertyThatChanges // set x after the animation is enabled or disabled
Behavior on x
id: xBehavior
NumberAnimation
duration: 500
如果 x 将被设置为比以前更大的值,它将启用动画,否则将其禁用。
关于替代实现的其他说明:如果您不想为此中间侦听器使用新的property real
,则可以将Connections
对象直接绑定到somePropertyThatChanges
。我没有包括这个,因为我相信他们在我的 Qt 版本(5.12)和你的之间改变了这些语法,但对我来说它看起来像:
Connections
target: root
onSomePropertyThatChangesChanged: // in QT 5.15 this may need to instead be: function onSomePropertyThatChangesChanged()
if (root.somePropertyThatChanges > rect.x) // same logic
xBehavior.enabled = true
else
xBehavior.enabled = false
rect.x = somePropertyThatChanges
【讨论】:
以上是关于如何使 QML 动画仅在属性值增加而不是减少时才起作用?的主要内容,如果未能解决你的问题,请参考以下文章