zoukankan      html  css  js  c++  java
  • 27.Qt Quick QML-State、Transition

    1.State
    所有组件均具有默认状态,该状态定义对象和属性值的默认配置。可以通过向States属性添加State组件来定义新状态,以允许组件在不同配置之间切换.
    许多用户界面设计都是由State状态实现的,比如: 交通信号将根据其State配置来实现红黄绿灯交错亮灭.
    在QML中,状态是在State对象中定义的一组属性配置。例如,下面几种用State状态最为方便:

    • 只显示某些UI组件,隐藏其他组件
    • 向用户展示不同的可用操作
    • 启动、停止或暂停动画
    • 更改特定Item的属性值
    • 显示不同的视图或screen

    所有基于Item的对象都有一个states属性state属性:

    • states属性 : list<State>类型,用来保存多个不同State对象的列表.
    • state属性 : string类型,用来保存对象当前State对象的名称(表示当前状态是什么样子的),默认是一个空字符串,如果要改变Item对象当前状态,则将state属性设置为要改变的状态name名称即可.

    对于非Item对象可以通过StateGroup组件配合来使用State即可


    1.1 State对象属性

    • name : string,状态名称。,每个状态在都应具有唯一的名称
    • changes : list<Change>,保存当前State下的多个Change对象,比如PropertyChanges、StateChangeScript、ParentChange等
    • extend : string,扩展,表示该状态要在哪个State的基础上进行扩展,当一个状态要在另一个状态基础上进行扩展时,它将继承该另一个状态的所有changes
    • when : bool,当什么时候启动状态,默认值为false,比如:when: mouseArea.pressed,表示当有鼠标按下则启动该状态.

    1.2 Change对象

    当一个对象的状态发生改变,那么该对象展示给用户的效果也会相应发生改变,所以State支持了多个不同Change对象供我们使用,有如下几种:

    • PropertyChanges: 改变对象的属性值
    • StateChangeScript:运行脚本,比如function函数
    • ParentChange: 改变对象的父类对象.并且改变对象在父类对象下的坐标xy,宽高等属性
    • AnchorChanges: 改变对象的anchor值

    由于帮助手册都有很多示例,所以我们以PropertyChanges为例,来实现一个交通灯

    1.3 交通灯示例

    我们以交通信号为例,根据其State配置来实现红黄绿灯交错亮灭.效果如下所示:

    代码如下所示:

    Window {
         300;
        height: 400;
        visible: true;
        property var delayCnt: 0
    
        Rectangle {
            anchors.fill: parent
            gradient: Gradient {
                GradientStop { position: 0.0; color: "#14148c" }
                GradientStop { position: 0.699; color: "#14aaff" }
                GradientStop { position: 0.7; color: "#80c342" }
                GradientStop { position: 1.0; color: "#006325" }
            }
        }
    
        Canvas {
            id: canvas
            anchors.centerIn: parent
             80
            height: 300
            onPaint: {
                var ctx = getContext("2d")
                ctx.fillStyle = "black"
                ctx.fillRect(0,0,width,height-90)
                ctx.fillRect(width/2 -15,height-90,30,90)
            }
        }
    
        Column {
            id: leds
            anchors.centerIn: canvas
            anchors.verticalCenterOffset: -45
            spacing: 15
            state: delayCnt < 5 ? "red" :
                   delayCnt < 10 ? "green" :
                   delayCnt < 14 ? (delayCnt%2==0 ? "green" : "") :
                   "yellow";
    
            Rectangle {
                id : redLed
                 50; height:50
                radius: width/2
                color: "red"
                opacity: 0.2
            }
            Rectangle {
                id : yellowLed
                 50; height:50
                radius: width/2
                color: "yellow"
                opacity: 0.2
            }
            Rectangle {
                id : greenLed
                 50; height:50
                radius: width/2
                color: "green"
                opacity: 0.2
            }
    
            states: [
                State {
                    name: "red"
                    PropertyChanges { target: redLed; opacity: 1}
                },
                State {
                    name: "yellow"
                    PropertyChanges { target: yellowLed; opacity: 1}
                },
                State {
                    name: "green"
                    PropertyChanges { target: greenLed; opacity: 1}
                }
            ]
        }
        Timer {
            interval: 500
            repeat: true
            running: true
            onTriggered: {
                delayCnt = (delayCnt+1)%18
                console.log(delayCnt,leds.state)
            }
        }
    }

    2.Transition
    Transition用来当State发生改变时产生的一个过渡动画(有Transition的地方就会有State出现),使得状态改变更加平滑。
    并且所有基于Item的对象都有一个transitions属性,是一个list<Transition>类型,保存着该对象所有的Transtion,只要当该对象的state发生改变时,就会去遍历transitions属性,如果有满足条件的,则产生一个过渡动画.
    给transitions赋值和给states赋值一样,假如只有一个Transition,那么我们可以直接这样写:

    transitions: Transition {
    ... ...
    }

    假如有多个Tansition,可以这样写:

    transitions: [
        Transition {
            ... ...
        },
        Transition {
            ... ...
        } 
    ]

    2.1 Transition对象属性

    • animations : list<Animation>,default默认属性,此属性保存Transition中的动画列表。
    • enabled : bool,Transition使能,默认为true,如果为false则禁止
    • from : string,默认值为"*"(任何状态),只要我们未设置from,那么每次转换到另一个状态时,就会将当前状态赋到from中
    • to : string,默认值为"*"(任何状态),只要我们未设置to,那么每次转换到另一个状态时,就会将另一个状态赋到to中
    • reversible : bool,是否让动画进行反转,默认为false,只有当Transition使用了SequentialAnimation串行动画时,我们需要设置为true
    • running : bool,只读属性,保存当前是否在运行中.

    2.2 使用串行动画时注意

    • 一个Transition可以包含多个动画,并且多个动画默认为并行执行的,所以我们不需要设置reversible为true,因为这些动画没有先后顺序.
    • 只有当Transition使用了SequentialAnimation串行动画时,我们才需要设置为true
    • 如果属性同时绑定在Transition包含的动画里和Behavior包含的动画里,那么Behavior将会被代替

    2.3 在交通灯基础上添加过渡动画

    我们在上个示例的leds对象中添加下面代码:

    transitions: Transition {
                PropertyAnimation  { target: redLed;  property: "opacity"; duration: 400}
                PropertyAnimation  { target: yellowLed;  property: "opacity"; duration: 400}
                PropertyAnimation  { target: greenLed;  property: "opacity"; duration: 400}
    }
    • 只要当redLed、yellowLed、greenLed中的opacity属性发生改变时,就会产生一个400ms的过渡动画.

    最终效果如下所示:


    人间有真情,人间有真爱。

    如果您喜欢这里,感觉对你有帮助,并且有多余的软妹币的话,不妨投个食吧,赞赏的时候,留下美句和你的博客地址哦~   戳这里看谁投食了


查看全文
  • 相关阅读:
    Office文档在线编辑的实现之二
    Office文档在线编辑的实现之一
    WebIM(5)----将WebIM嵌入到页面中
    WebIM(4)----Comet的特殊之处
    WebIM(3)----性能测试
    WebIM(2)---消息缓存
    WebIM(1)
    微信的通讯录首字母滑动的实现
    新浪微博认证新API调用
    Android小感悟-重写textview组件感悟
  • 原文地址:https://www.cnblogs.com/lifexy/p/14854427.html
  • Copyright © 2011-2022 走看看