QML实现动态时间的炫酷效果(类似八卦图)

废话不多说,先看效果:
请添加图片描述
整个工程全用QML代码实现,内部实现定时器,并且定义动画效果,完整源码如下所示(有完整的注释):
SelfText.qml

import QtQuick 2.0

Text {
    id: textContent
    text: qsTr("")
    font.pointSize: 10
    anchors.centerIn: parent
}

main.qml

import QtQuick 2.0
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15

/*
实现原理:
实际上圆形区域是默认构造出来的三个Rectangle 每个Rectangle中是一堆Text
每次触发定时器时 都是旋转Rectangle实现时间走动
*/

//根节点设置为Rectangle是因为可以设置color属性
Rectangle {
    id: qmlClockRoot
    color: "#c0c0c0"

    //定义属性
    property  string currHour
    property  string currMinute
    property  string currSecond
    property string textColor: "#808080"
    property string strList: "零一二三四五六七八九"

    //定时时分秒层
    Rectangle{
        id:rectHour
        //这里一定要设置背景透明-因为是铺满父窗口的
        color: "#00000000"
        anchors.fill: parent
    }
    Rectangle{
        id:rectMinute
        //这里一定要设置背景透明-因为是铺满父窗口的
        color: "#00000000"
        anchors.fill: parent
    }
    Rectangle {
        id:rectSecond
        //这里一定要设置背景透明-因为是铺满父窗口的
        color: "#00000000"
        anchors.fill: parent
    }

    //定义时分秒文字提示
    SelfText{
        id:textHour
        text: "\t\t\t\t\t\t\t\t秒"
        color: textColor
        font.pointSize: 12
    }
    SelfText{
        id:textMinute
        text: "\t\t\t\t\t\t分"
        color: textColor
        font.pointSize: 12
    }
    SelfText{
        id:textSecond
        text: "\t\t\t\t时"
        color: textColor
        font.pointSize: 12
    }

    //定义中心显示日期组件
    Column {
        spacing: 5
        //放在中间
        anchors.centerIn: parent
        Text{
            id:textWeek
            text: ""
            color: textColor
            font.pointSize: 14
            //放在中间
            anchors.horizontalCenter: parent.horizontalCenter
        }
        Text{
            id:textDate
            text: ""
            color: textColor
            font.pointSize: 14
            //放在中间
            anchors.horizontalCenter: parent.horizontalCenter
        }
    }

    //定义旋转角动画效果
    RotationAnimation{
        id:aniHour
        target: rectHour
        //指定动画时间200ms
        duration: 200
        //这里旋转指定最小角度旋转
        direction: RotationAnimation.Shortest
    }
    RotationAnimation{
        id:aniMinute
        target: rectMinute
        //指定动画时间200ms
        duration: 200
        //这里旋转指定最小角度旋转
        direction: RotationAnimation.Shortest
    }
    RotationAnimation{
        id:aniSecond
        target: rectSecond
        //指定动画时间200ms
        duration: 200
        //这里旋转指定最小角度旋转
        direction: RotationAnimation.Shortest
    }

    //当组件加载完成时
    Component.onCompleted: {
        //初始化界面元素-时
        calcHourAndShow()
        //初始化界面元素-分
        calcMinuteAndShow()
        //初始化界面元素-秒
        calcSecondAndShow()
        //初始化一次界面
        timerCall()
        //启动定时器
        timer.start()
    }

    Timer{
        id:timer
        //设置执行间隔-这里设置小一点才能尽量保证和系统时间一致
        interval: 100
        //设置是否重复
        repeat: true
        //设置定时器回调
        onTriggered: {
            timerCall()
        }
    }

    //定时器执行回调函数
    function timerCall(){
        textWeek.text=getCurrentWeek()
        textDate.text=getCurrentDate()
        //这里获取出来的时间需要先转成整数 因为时间是0-59而文字是1-60 所以这里需要减一
        var tmpHour=getCurrentHour()
        if(currHour!==tmpHour){
            currHour=tmpHour
            aniHour.from=(parseInt(getCurrentHour()) - 2) * (-30)
            aniHour.to=(parseInt(getCurrentHour()) - 1) * (-30)
            aniHour.running=true
        }
        var tmpMinute=getCurrentMinute()
        if(currMinute!==tmpMinute){
            currMinute=tmpMinute
            aniMinute.from=(parseInt(getCurrentMinute()) - 2) * (-6)
            aniMinute.to=(parseInt(getCurrentMinute()) - 1) * (-6)
            aniMinute.running=true
        }
        var tmpSecond=getCurrentSecond()
        if(currSecond!==tmpSecond){
            currSecond=tmpSecond
            currSecond.from=(parseInt(getCurrentSecond()) - 2) * (-6)
            aniSecond.to=(parseInt(getCurrentSecond()) - 1) * (-6)
            aniSecond.running=true
        }
    }

    //计算并加载时分秒-时
    function calcHourAndShow(){
        //动态加载组件
        var component = Qt.createComponent("SelfText.qml")
        if(component.status===Component.Ready){
            //计算12个小时的文字
            var angle = 0
            for(var i=1;i<=12;++i){
                var tmpStr=""
                if(i<10){
                    tmpStr=strList[i]
                }
                else{
                    //这里一定要用parseInt或者Math.floor取整数 否则计算出来可能是小数
                    tmpStr=strList[parseInt(i/10)]
                    tmpStr=tmpStr+strList[i%10]
                }
                //动态创建组件-注意这里是创建-指定父类为Hour
                var tmpText=component.createObject(rectHour)
                tmpText.text="\t\t\t" + tmpStr
                tmpText.rotation = angle
                angle = i*30
            }
        }
    }

    //计算并加载时分秒-分
    function calcMinuteAndShow(){
        //动态加载组件
        var component = Qt.createComponent("SelfText.qml")
        if(component.status===Component.Ready){
            //计算60个分的文字
            var angle = 0
            for(var i=1;i<=60;++i){
                var tmpStr=""
                if(i<10){
                    tmpStr=strList[i]
                }
                else{
                    //这里一定要用parseInt或者Math.floor取整数 否则计算出来可能是小数
                    tmpStr=strList[parseInt(i/10)]
                    tmpStr=tmpStr+strList[i%10]
                }
                if(tmpStr=='六零'){
                    tmpStr='零零'
                }
                //动态创建组件-注意这里是创建-指定父类为Minute
                var tmpText=component.createObject(rectMinute)
                tmpText.text="\t\t\t\t\t" + tmpStr
                tmpText.rotation = angle
                angle = i*6
            }
        }
    }

    //计算并加载时分秒-秒
    function calcSecondAndShow(){
        //动态加载组件
        var component = Qt.createComponent("SelfText.qml")
        if(component.status===Component.Ready){
            //计算60个秒的文字
            var angle = 0
            for(var i=1;i<=60;++i){
                var tmpStr=""
                if(i<10){
                    tmpStr=strList[i]
                }
                else{
                    //这里一定要用parseInt或者Math.floor取整数 否则计算出来可能是小数
                    tmpStr=strList[parseInt(i/10)]
                    tmpStr=tmpStr+strList[i%10]
                }
                if(tmpStr=='六零'){
                    tmpStr='零零'
                }
                //动态创建组件-注意这里是创建-Second
                var tmpText=component.createObject(rectSecond)
                tmpText.text="\t\t\t\t\t\t\t" + tmpStr
                tmpText.rotation = angle
                angle = i*6
            }
        }
    }

    //获取时分秒
    function getCurrentHour(){
        return Qt.formatDateTime(new Date(),"h")
    }
    function getCurrentMinute(){
        return Qt.formatDateTime(new Date(),"m")
    }
    function getCurrentSecond(){
        return Qt.formatDateTime(new Date(),"s")
    }
    //获取年月日
    function getCurrentDate(){
        return Qt.formatDateTime(new Date(),"yyyy年MM月dd日")
    }
    //获取星期几
    function getCurrentWeek(){
        return Qt.formatDateTime(new Date(),"dddd")
    }
}
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值