QMLCanvas绘制⼀个简单的仪表盘
QML 的 Canvas 提供了⼀个 2D 画布,⽀持所有 HTML5 2D 上下⽂像素操作。使⽤ QML Canvas 应该避免频繁的更新和动画处理,如果可能的话,最好使⽤QQuickPaintedItem并通过QPainter在C ++中实现绘图,⽽不是使⽤更昂贵且性能可能更低的JavaScript和Context2D⽅法。
这次我试着画了⼀个简单的仪表盘,效果和完整代码如下(如果要好看的表盘,还是要配合贴图):
实现代码两个QML⽂件:
//MyDial.qml
import QtQuick 2.12
import QtQuick.Controls 2.12
//表盘
//⽬前只实现了简单的,⼀些细节还没做,如刻度的取值浮点数⼩数
Item {
id: control
property int lineWidth: 3
property int fontPx: 16
property color themeColor: "#00C1DE"
property int padding: 20
property int radius: (width/2<height)?(width/2-2*padding):(height-2*padding)
property int half: control.radius+control.padding
property double minValue: 0
property double maxValue: 100
property double currentValue: 0
property int stepSize: 6
property double stepValue: (control.maxValue-control.minValue)/(stepSize-1)
property double stepAngle: Math.PI/(control.stepSize-1)
onCurrentValueChanged: {
}
//背景刻度
Canvas{
id: canvas
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
width: control.half*2
//底部也有⼀个padding
height: control.half+control.padding
onPaint: {
let ctx=getContext("2d");
let ctx=getContext("2d");
ctx.lineWidth=control.lineWidth;
ctx.font=String(control.fontPx)+"px SimHei bold"
ctx.fillStyle=control.themeColor;
ctx.strokeStyle=control.themeColor;
ctx.lineCap="round";
ctx.clearRect(0,0,width,height);
//原点平移
ctx.save();
canvas动画
ctx.beginPath();
//radius-linewidth
//x,y,r,起始⾓右侧,终⽌⾓顺时针旋转
ctx.arc(0,0,control.radius,Math.PI,2*Math.PI);
//绘制刻度
ctx.save();
for(let i=control.minValue;i<control.maxValue+1;i+=control.stepValue){
ctx.lineTo(0,-control.radius);
ctx.fillText(String(i),-10,-control.radius+10+control.fontPx)
}
ctx.stroke();
ctx.beginPath();
//绘制指针
ctx.arc(0,0,5,0,2*Math.PI);
ctx.lineTo(0,-5);
ctx.stroke();
}
}
function setValue(value){
if(value<control.minValue||value>control.maxValue)
return;
control.currentValue=value;
}
}
//main.qml
import QtQuick 2.12
import QtQuick.Window 2.12
Window {
id: root
visible: true
width: 640
height: 480
title: qsTr("龚建波 1992")
Column{
spacing: 20
MyDial{
id: dial
width: root.width-40
height: width/2
//测试⽤,查看canvas范围
Rectangle{
anchors.fill: parent
color: "transparent"
radius: 10
border.width: 2
}
}
Text{
anchors.horizontalCenter: parent.horizontalCenter text: "当前值:"+String(dial.currentValue)
font.pixelSize: 20
color: dial.themeColor
}
}
//测试⽤,点击增加值
MouseArea{
anchors.fill: parent
onClicked:{
//dial.setValue(100);
if(dial.currentValue<dial.maxValue){
dial.currentValue+=dial.stepValue;
}else{
dial.currentValue=dial.minValue;
}
}
}
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论