Qt Quick 演示 - 时钟

一个 QML 时钟应用程序,展示如何使用 ListView 类型显示由 ListModel 生成的数据,以及使用 SpringAnimation 类型动画显示图像。

时钟 展示如何使用 ListView 类型显示由 ListModel 生成的数据。模型使用的代理类型指定为 Clock.qml 文件中指定的自定义 QML 类型。

使用 JavaScript 方法获取不同时区中几个城市的当前时间,并使用 QML 类型在带有动画时针的时钟面上显示时间。

运行示例

要从 Qt Creator 运行示例,请进入 欢迎模式 并从 示例 中选择示例。有关更多信息,请访问 构建和运行示例

显示由列表模型生成的数据

在 clocks.qml 文件中,我们使用 Rectangle 类型创建应用程序主窗口

Rectangle {
    id: root
    width: 640; height: 320
    color: "#646464"

我们使用 ListView 类型显示由 ListModel 类型提供的项目列表

    ListView {
        id: clockview
        anchors.fill: parent
        orientation: ListView.Horizontal
        cacheBuffer: 2000
        snapMode: ListView.SnapOneItem
        highlightRangeMode: ListView.ApplyRange

        delegate: Content.Clock { city: cityName; shift: timeShift }
        model: ListModel {
            ListElement { cityName: "New York"; timeShift: -4 }
            ListElement { cityName: "London"; timeShift: 0 }
            ListElement { cityName: "Oslo"; timeShift: 1 }
            ListElement { cityName: "Mumbai"; timeShift: 5.5 }
            ListElement { cityName: "Tokyo"; timeShift: 9 }
            ListElement { cityName: "Brisbane"; timeShift: 10 }
            ListElement { cityName: "Los Angeles"; timeShift: -8 }
        }
    }

列表元素的定义方法与其他 QML 类型类似,只是它们包含了一组 role 定义,而不仅仅是属性。Role 既有定义如何访问数据的功能,也包含了数据本身。

对于每个列表元素,我们使用 cityName role 指定城市的名称,以及使用 timeShift role 指定时区作为从 UTC(协调世界时)的正或负偏移量。

将自定义类型的 Clock 用于 ListViewdelegate,定义列表项的视觉外观。要使用 Clock 类型,我们添加一个导入语句,导入位于 content 中的文件夹,该类型就位于此文件夹中

import "content" as Content

我们使用 Image 类型来显示指向箭头,指示用户是否可以滑动视图以看到更多时钟的左侧或右侧

    Image {
        anchors.left: parent.left
        anchors.bottom: parent.bottom
        anchors.margins: 10
        source: "content/arrow.png"
        rotation: -90
        opacity: clockview.atXBeginning ? 0 : 0.5
        Behavior on opacity { NumberAnimation { duration: 500 } }
    }

    Image {
        anchors.right: parent.right
        anchors.bottom: parent.bottom
        anchors.margins: 10
        source: "content/arrow.png"
        rotation: 90
        opacity: clockview.atXEnd ? 0 : 0.5
        Behavior on opacity { NumberAnimation { duration: 500 } }
    }
}

我们使用 opacity 属性在列表视图位于 x 轴的起始或结束位置时隐藏箭头。

在 Clock.qml 中,我们定义了一个 timeChanged() 函数,在其中使用 JavaScript Date 对象的方法获取 UTC 当前的当前时间,并将其调整到正确的时间区

    function timeChanged() {
        var date = new Date;
        hours = internationalTime ? date.getUTCHours() + Math.floor(clock.shift) : date.getHours()
        night = ( hours < 7 || hours > 19 )
        minutes = internationalTime ? date.getUTCMinutes() + ((clock.shift % 1) * 60) : date.getMinutes()
        seconds = date.getUTCSeconds();
    }

我们使用 Timer 类型以 100 毫秒的间隔更新时间

    Timer {
        interval: 100; running: true; repeat: true;
        onTriggered: clock.timeChanged()
    }

我们在一个图像类型中使用 Item 类型来显示模拟时钟面上的时间。对白天和夜晚不同小时使用不同的图像

    Item {
        anchors.centerIn: parent
        width: 200; height: 240

        Image { id: background; source: "clock.png"; visible: clock.night == false }
        Image { source: "clock-night.png"; visible: clock.night == true }

应用于 Image 类型的 Rotation 变换为旋转时钟指针提供了一种方法。代码的 origin 属性保存一个相对于父对象固定的点,当其他部分旋转时,该点保持固定。angle 属性决定顺时针旋转指针的角度。

        Image {
            x: 92.5; y: 27
            source: "hour.png"
            transform: Rotation {
                id: hourRotation
                origin.x: 7.5; origin.y: 73;
                angle: (clock.hours * 30) + (clock.minutes * 0.5)
                Behavior on angle {
                    SpringAnimation { spring: 2; damping: 0.2; modulus: 360 }
                }
            }
        }

        Image {
            x: 93.5; y: 17
            source: "minute.png"
            transform: Rotation {
                id: minuteRotation
                origin.x: 6.5; origin.y: 83;
                angle: clock.minutes * 6
                Behavior on angle {
                    SpringAnimation { spring: 2; damping: 0.2; modulus: 360 }
                }
            }
        }

        Image {
            x: 97.5; y: 20
            source: "second.png"
            transform: Rotation {
                id: secondRotation
                origin.x: 2.5; origin.y: 80;
                angle: clock.seconds * 6
                Behavior on angle {
                    SpringAnimation { spring: 2; damping: 0.2; modulus: 360 }
                }
            }
        }

        Image {
            anchors.centerIn: background; source: "center.png"
        }

当时间变化时,我们在 angle 属性上使用 Behavior 类型来应用 SpringAnimation。spring 和 damping 属性启用类似弹簧的运动,而 modulus 为 360 的使其动画目标值在完整圆上循环。

我们使用 Text 类型在时钟下方显示城市名称

        Text {
            id: cityLabel
            y: 210; anchors.horizontalCenter: parent.horizontalCenter
            color: "white"
            font.family: "Helvetica"
            font.bold: true; font.pixelSize: 16
            style: Text.Raised; styleColor: "black"
        }

示例项目 @ code.qt.io

另请参阅 QML 应用

© 2024 Qt 公司。此处所包含的文档贡献是各自所有者的版权。此处提供的文档是根据自由软件基金会发布的 GNU Free Documentation License version 1.3 的条款许可的。Qt 和相应的标志是芬兰和/或其他国家的 Qt 公司的商标。所有其他商标均为其各自所有者的财产。