结合使用 Animators 和 PropertyAnimation 的 QML 过渡动画

Posted

技术标签:

【中文标题】结合使用 Animators 和 PropertyAnimation 的 QML 过渡动画【英文标题】:QML Transition Animation using Animators and PropertyAnimation Combined 【发布时间】:2020-09-23 10:52:19 【问题描述】:

在状态转换动画中使用 QML Animatiors 时遇到一些问题。这是我的工作示例代码。在这个示例中,如果我决定不为 OpacityAnimator 提供“来自”属性(原因是我希望它考虑当前属性值),则动画师不会为属性设置动画。

import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
import QtQuick.Window 2.12

Window 
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    property bool isOpen: false
    Button 
        anchors.centerIn: parent
        text: "Fade Animation Open Layer "
        onClicked: 
            isOpen = true;
            overlay.state = "open";
        
    
    Rectangle 
        id: overlay
        anchors.fill: parent
        color: "green"
        visible: isOpen
        opacity: 0
        Button 
            anchors.centerIn: parent
            text: "Close Overlay"
            onClicked: 
                overlay.state = "close"
            
        

        state: "close"
        states: [
            State 
                name: "hidden"
            ,
            State 
                name: "visible"
            
        ]
        transitions: [
            Transition 
                from: "close"
                to: "open"
                OpacityAnimator 
                    target: overlay
                    from: 0.0
                    to: 1.0
                    duration: 600
                    easing.type: Easing.OutCubic
                


            ,
            Transition 
                from: "open"
                to: "close"
                SequentialAnimation 
                    OpacityAnimator 
                        target: overlay
                        //from: overlay.opacity
                        to: 0.0
                        duration: 600
                        easing.type: Easing.OutCubic
                    
                    ScriptAction 
                        script: 
                            isOpen = false;
                        
                    

                
            
        ]
    

如果我改用 PropertyAnimation,淡入淡出效果绝对没问题。所以我只是深入研究了 Animator Code 并从 qquickanimator.cpp 的 apply 函数中找到了下面的 sn-p 并假设这意味着如果未指定“from”,它应该从目标的属性值和注释中获取它声称魔术线的工作原理类似于 PropertyAnimation。但它不是这样工作的

    if (isFromDefined)
        job->setFrom(from);
    else if (action.fromValue.isValid())
        job->setFrom(action.fromValue.toReal());
    else
        job->setFrom(action.property.read().toReal());

// This magic line is in sync with what PropertyAnimation does
// and prevents the animation to end up in the "completeList"
// which forces action.toValue to be written directly to
// the item when a transition is cancelled.
 action.fromValue = action.toValue;

所以我的问题是:

    这是 Qt Animator 中的错误还是我在这里遗漏了什么? 如果 Animators 范围是场景图并且 PropertyAnimation 是目标对象,是否可以在分组动画(顺序或并行)中组合 PropertyAnimation 和 Animators(Opacity、Scale)以实现状态转换

【问题讨论】:

只是一条评论告诉我我真的不喜欢 QML 中的状态和转换。大多数时候,行为已经绰绰有余,而且不那么冗长。我什至为常见任务编写了一些自定义的。在这里它适用于您的代码:gist.github.com/oKcerG/c2da0dfb077b661a4afdb03930fb941e 1.这不是一个错误。动画器用于在渲染线程而不是 UI 线程中运行动画。所以从 UI 线程的角度来看 opacity 值会从 0 跳转到 1,反之亦然。来自文档:“QML 属性的值将在动画完成后更新。动画运行时该属性不会更新。” 【参考方案1】:

请参阅文档中有关 Animator 的 from 属性的评论:

如果 Animator 是在一个 Transition 或 Behavior 中定义的,则该值默认为在 Transition 的起始状态中定义的值,或者是触发 Behavior 时属性的当前值。

我认为这意味着它将使用来自open 状态的1.0to 值,而不是目标上的当前值。似乎状态机正在跟踪和使用转换如何离开事物而不是当前值。

您的from: overlay.opacity 应该解决该问题吗?

【讨论】:

我怀疑状态转换操作可能是在转换后缓存目标属性并重新应用于“从”。是的,使用 from: overlay.opacity 确实有效。 PropertyAnimation 运行良好,尽管在过渡动画中没有“from”,并且只有以这种方式运行的 Animators。使用 Animators 是首选,因为它具有非阻塞 UI 线程性质。由于我们有许多 Animator 分组,使用 from 会导致不太平滑的过渡。 您能否进一步解释您的最后评论? from 导致分组动画师运行不顺畅?你能更详细地解释一下“不太顺利”是什么意思吗?

以上是关于结合使用 Animators 和 PropertyAnimation 的 QML 过渡动画的主要内容,如果未能解决你的问题,请参考以下文章

UIScrollView和UIPageControl结合使用

Vue实例理解

spring 结合Druid连接池

python__高级 : Property 的使用

Dependency Property 依赖属性

Dependency Property 依赖属性