作者: 一去、二三里
个人微信号: 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
}
}
}