QML 自定义组件(时钟)

作者: 一去、二三里
个人微信号: iwaleon
微信公众号: 高效程序员

在 QML 开发过程中,经常需要自定义组件,这有利于我们的代码复用性、模块化、以及扩展性。通过使用自定义组件,不但可以提高开发效率,降低维护成本,还可以快速构建出功能丰富、灵活可扩展的 QML 应用程序。

另外,想学好 QML,一个好的老师必不可少,这里顺便推荐一个很棒、很强的教程:《细说 QML》。有了它,精通 QML 不是梦!

今天,我们要分享的是一个 Clock 组件,通过这个组件,可以实现各种大小、样式风格的时钟,来欣赏一下效果图。

在这里插入图片描述

左侧是默认样式,右侧可以通过鼠标点击随机变换样式。

逻辑控制

为了实现 Clock 组件,我们先进行一些职责划分,将显示部分放在独立的 QML 文件中完成,逻辑控制部分放在 JS 文件中完成。

要绘制时钟,按照步骤拆分,需要有背景、数字、时针等,以下是 clock.js 中的部分代码:

this.draw = function(ctx) {
    
    
    ctx.clearRect(0, 0, 300, 300)

    ctx.save()

    var time = new Date()
    var hours = time.getHours()
    var minutes = time.getMinutes()
    var seconds = time.getSeconds()

    // 1. 绘制背景
    this.drawBackground(ctx)
    // 2. 绘制的数字
    this.drawNumbers(ctx)
    // 3. 绘制时针
    this.drawHour(ctx, hours, minutes, seconds)
    // 4. 绘制分针
    this.drawMinute(ctx, minutes, seconds)
    // 5. 绘制秒针
    this.drawSecond(ctx, seconds)
    // 6. 绘制圆心
    this.drawCircle(ctx)
    // 7. 绘制时针的刻度
    this.drawHourTick(ctx)
    // 8. 绘制分针的刻度
    this.drawMinuteTick(ctx)

    ctx.restore()
}

组件封装

具体的组件,则放在 Clock.qml 文件中。为了便于控制样式,它对外提供了一系列属性,例如:backgroundColor、circleColor 等。

import QtQuick
import "qrc:/js/clock.js" as JsClock

Item {
    
    
    property color backgroundColor: "white"
    property color circleColor: "gray"
    property color circleBorderColor: "black"
    property color borderColor: "black"
    property int borderWidth: 2
    property color numberColor: "black"
    property color hourColor: "black"
    property color minuteColor: "black"
    property color secondColor: "orange"
    property color hourTickColor: "black"
    property color minuteTickColor: "black"

    Canvas {
    
    
        id: clockCanvas
        anchors.fill: parent

        property var clock: new JsClock.Clock()

        onPaint: {
    
    
            draw()
        }

        // 绘制钟表
        function draw() {
    
    
            var ctx = getContext("2d")

            ctx.save()
            var scaleX = width / 300
            var scaleY = height / 300
            ctx.scale(scaleX, scaleY)
            setStyle()
            clock.draw(ctx)
            ctx.restore()

            requestAnimationFrame(draw)
        }

        // 设置样式
        function setStyle() {
    
    
            clock.setBackgroundColor(backgroundColor)
            clock.setCircleColor(circleColor)
            clock.setCircleBorderColor(circleBorderColor)
            clock.setBorderColor(borderColor)
            clock.setBorderWidth(borderWidth)
            clock.setNumberColor(numberColor)
            clock.setHourColor(hourColor)
            clock.setMinuteColor(minuteColor)
            clock.setSecondColor(secondColor)
            clock.setHourTickColor(hourTickColor)
            clock.setMinuteTickColor(minuteTickColor)
        }
    }
}

组件使用

组件有了之后,就可以像其他元素一样使用它了。我们分别实现两个钟表,一个是默认样式的,一个可以通过鼠标点击随机变色。

import QtQuick
import QtQuick.Layouts
import "../component"

Rectangle {
    
    
    id: clockPage

    // 取值范围 [min, max]
    function randomNumber(min, max) {
    
    
        return Math.floor((Math.random() * (max - min + 1)) + min)
    }

    // 随机颜色
    function randomColor() {
    
    
        return Qt.rgba(randomNumber(0, 1), randomNumber(0, 1), randomNumber(0, 1), 1)
    }

    RowLayout {
    
    
        anchors.fill: parent
        spacing: 10

        Item {
    
    
            Layout.fillWidth: true
        }

        Clock {
    
    
            width: 300
            height: 300
        }

        Clock {
    
    
            id: randomClock
            width: 400
            height: 400

            function setRandomStyle() {
    
    
                randomClock.backgroundColor = randomColor()
                randomClock.circleColor = randomColor()
                randomClock.circleBorderColor = randomColor()
                randomClock.borderColor = randomColor()
                randomClock.borderWidth = randomNumber(5, 20)
                randomClock.numberColor = randomColor()
                randomClock.hourColor = randomColor()
                randomClock.minuteColor = randomColor()
                randomClock.secondColor = randomColor()
                randomClock.hourTickColor = randomColor()
                randomClock.minuteTickColor = randomColor()
            }

            MouseArea {
    
    
                anchors.fill: parent
                onClicked: randomClock.setRandomStyle()
            }

            Component.onCompleted: setRandomStyle()
        }

        Item {
    
    
            Layout.fillWidth: true
        }
    }
}

猜你喜欢

转载自blog.csdn.net/u011012932/article/details/131524988