1.效果
2.源码
import QtQuick 2.0
Item {
property int min: 0
property int max: 100
property int value: 70
property int rangeLineWidth: 20
property color rangeLineColor: "#f2f2f2"
property int valueLineWidth: 20
property color valueLineColor: "#33ccff"
property bool dropShadow: true
property alias textSize: progressText.font.pixelSize
property alias textColor: progressText.color
//百分比
property real percentage:(value-min) / (max-min)
property real startAngle: Math.PI/2;
property real endAngle: ((Math.PI*2)*percentage + startAngle);
Canvas {
id:canvas
anchors.centerIn: parent
width: Math.min(parent.width,parent.height)
height: Math.min(parent.width,parent.height)
onPaint:{
var ctx = getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.lineCap = "round";
drawRange(ctx);
drawValue(ctx);
}
function drawRange(ctx){
ctx.beginPath();
ctx.arc(canvas.width/2, canvas.height/2, arcRadius(), 0, Math.PI*2, true);
ctx.lineWidth = rangeLineWidth;
ctx.strokeStyle = rangeLineColor;
ctx.stroke();
}
function drawValue(ctx){
ctx.save();
//阴影效果大尺寸画布比较吃性能 小尺寸仍然流畅
// ctx.shadowColor= valueLineColor;
// ctx.shadowBlur= valueLineWidth/4;
ctx.beginPath();
ctx.arc(canvas.width/2, canvas.height/2, arcRadius(), startAngle,endAngle, false);
ctx.lineWidth = valueLineWidth;
ctx.strokeStyle = valueLineColor;
ctx.stroke();
ctx.restore();
}
function currentAngle(){
var angle = Math.PI*2 * (value-min) / (max-min);
angle = Math.PI*2 - angle;
return angle;
}
function arcRadius(){
return Math.min(canvas.height,canvas.width)/2 - Math.max(rangeLineWidth,valueLineWidth);
}
}
Text {
id: progressText
anchors.centerIn: parent
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
//粗略计算放下5个字符最大字号
font.pixelSize: (Math.min(canvas.height,canvas.width) - Math.max(rangeLineWidth,valueLineWidth)) / 5;
text: "0%";
}
onMinChanged: refreshUI()
onMaxChanged: refreshUI()
onValueChanged: refreshUI()
Component.onCompleted: refreshUI()
function refreshUI(){
//计算百分比 保留一位小数
percentage = (value-min) / (max-min);
percentage = percentage.toFixed(3);
progressText.text = String("%1%").arg(percentage * 100);
//请求重新绘制
canvas.requestPaint()
}
}
3.用法
创建一个进度条,数字动画、滑动条,动画自动让环形进度循环增长,滑动条可以手动调节环形进度测试用。
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtGraphicalEffects 1.12
import QtQuick.Window 2.12
Window{
id:window
visible: true
width: 300
height: 300
ProgressRing{
id:progressbar
anchors.fill:parent
min:0
max:213
value:123
rangeLineWidth:40
}
NumberAnimation {
target: progressbar
property: "value"
from:0
to:213
duration:10000
running: true
loops: Animation.Infinite
}
Slider{
width:parent.width
from: 0
to:213
onValueChanged: {
progressbar.value = value
}
}
}