Author: Yiqu, Ersanli
Personal Wechat ID: iwaleon
Wechat Official Account: Efficient Programmer
In the QML development process, custom components are often required, which is beneficial to our code reusability, modularity, and scalability. By using custom components, not only can the development efficiency be improved, the maintenance cost can be reduced, but also feature-rich, flexible and scalable QML applications can be quickly built.
In addition, if you want to learn QML well, a good teacher is essential. By the way, I recommend a great and powerful tutorial: " Detailed QML ". With it, mastering QML is not a dream!
Today, what we want to share is a Clock component. Through this component, clocks of various sizes and styles can be realized. Let’s enjoy the renderings.
The left side is the default style, and the right side can change the style randomly by clicking the mouse.
logic control
In order to implement the Clock component, we first divide some responsibilities, put the display part in a separate QML file, and put the logic control part in a JS file.
To draw a clock, split it according to the steps, you need background, numbers, hour hand, etc. The following is part of the code in 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()
}
Component packaging
The specific components are placed in the Clock.qml file. In order to facilitate style control, it provides a series of properties, such as: backgroundColor, circleColor, etc.
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)
}
}
}
Component usage
Once you have a component, you can use it like any other element. We implement two clocks respectively, one is the default style, and the other can change color randomly by clicking the mouse.
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
}
}
}