QML 环形进度条canvas 98行代码实现

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
       }
   }
}

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我是唐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值