如何在 QML 转换结束时切换到另一个状态?

Posted

技术标签:

【中文标题】如何在 QML 转换结束时切换到另一个状态?【英文标题】:How to switch to another state at the end of a transition in QML? 【发布时间】:2014-04-07 02:43:22 【问题描述】:

我正在尝试实现一个健身应用程序,该应用程序显示当前锻炼名称,然后在休息期间显示一个进度条。当进度条填满时,显示下一个练习的名称,完成后显示进度条,以此类推。

请注意,我在此示例中使用了进度条,但在实际应用程序中我将拥有自己的小部件。

我的系统有两种状态:

exercise进度条的值为0并保持为0 rest在休息期间,进度条的值从 0 变为 maximumValue

原来是这样的:

    应用程序处于“练习”状态并显示当前练习的名称 用户执行练习并在完成后单击进度条 应用程序切换到“休息”状态 用户在进度条完成时休息 进度条完成后,应用程序切换回“练习”状态并显示下一个练习的名称

我的问题在于第 5 步:我不知道如何在转换结束时切换回另一个状态。我尝试在 PropertyChanges 期间更改“状态”属性,并在使用 SequentialAnimation 的转换结束时对其进行计时,但我收到以下错误消息:

QML StateGroup:无法将状态更改应用为状态定义的一部分。

这里是一些示例代码:

import QtQuick 2.0
import QtQuick.Controls 1.1

ProgressBar 
    id: root

    width: 200
    height: 48

    minimumValue: 0
    maximumValue: 100
    value: 76

    function switchState() 
        if (state == "exercise")
        
            state = "rest"
            return
        

        if (state == "rest")
        
            state = "exercise"
            return
        
    

    state: "exercise"

    states: [
        State 
            name: "exercise"
            PropertyChanges 
                target: root
                value: 0
            
        ,
        State 
            name: "rest"
            PropertyChanges 
                target: root
                value: maximumValue

                // error: QML StateGroup: Can't apply a state change as part of a state definition.
                // state: "exercise"
            
        
    ]

    transitions: [
        Transition 
            to: "rest"
            PropertyAnimation 
                target: root
                properties: "value"
                duration: 1000
            
        
    ]

    MouseArea 
        anchors.fill: parent
        onClicked: parent.switchState()
    

如何在状态转换结束时切换到另一个状态?

【问题讨论】:

一种选择是在最后触发一个计时器并从计时器滴答声中改变状态。 【参考方案1】:

我相信您可以通过使用转换中的 RunningChanged 信号来做到这一点:

transitions: [
    Transition 
        to: "rest"
        PropertyAnimation 
            target: root
            properties: "value"
            duration: 1000
        

        onRunningChanged: 
            if ((state == "rest") && (!running))
                switchState();
        
    
]

QML 对象具有属性更改的关联信号 (on<Property>Changed)。关联的处理程序通常不会记录在对象的引用中,但由于属性的存在而隐式可用。见this。

【讨论】:

【参考方案2】:

更新 我提出了一个错误的解决方案,因为一个错误,请见谅。 解决其问题的结果与@GabrielF 相同。所以我删除了它以避免重复。

但是下面的解决方案效果很好,可以让您在过渡/动画中进行精细控制。

还有另一种方式!

transitions: [
    Transition 
        to: "rest"
        SequentialAnimation 
            PropertyAnimation 
                target: root
                properties: "value"
                duration: 1000
            
            ScriptAction  script: switchState()     //<----
        
    
]    

请注意,在过渡动画中使用SequentialAnimation,您无需定义中间状态,只要确保完成特定动画即可。

祝你好运 - S.M.Mousavi

【讨论】:

根据docs on the stopped signal,“它只会为***的独立动画触发。它不会为行为或过渡中的动画或动画组中的动画触发。”所以我认为你的第一个和第二个例子行不通。 我真的很喜欢你上一个例子中的方法,我现在在我的应用程序中使用它并且效果很好。 我更喜欢使用 SequentialAnimation... ScriptAction script: ... 的这个解决方案,但第二个 PropertyAnimation 具有误导性,并且与 OP 的问题无关,所以我不能投票(目前)。注意:switchState() 周围的花括号不是必需的。 在转换过程中状态发生变化会发生什么?顺序动画会运行到结束并执行脚本动作吗?在文档中找不到它 @JohannesSchaub-litb 过渡行为是这样的:如果您在过渡期间更改状态,它将停止(暂停)该过渡并从当前值开始合适的过渡。

以上是关于如何在 QML 转换结束时切换到另一个状态?的主要内容,如果未能解决你的问题,请参考以下文章

如何制作跟踪/控制任何布尔属性的QML切换按钮

QML 从单击的矩形缩放到另一个 UI 元素

如何从一个网页顺利切换到另一个网页[关闭]

黑盒测试之状态转换测试法

如何将信号从一个 qml 发送到另一个

如何在 QML 中进行基于状态的模型更改