Qt QML 基于画布的扇形的进度条(Canvas)

Posted 火山上的企鹅

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Qt QML 基于画布的扇形的进度条(Canvas)相关的知识,希望对你有一定的参考价值。

Qt QML 基于画布的扇形的进度条


所有的热爱都要不遗余力,真正喜欢它便给它更高的优先级,和更多的时间吧!

GIT工程文件在这里:     QmlLearningPro编译选择 CanvasSector

QML其它文章请点击这里:     QT QUICK QML 学习笔记


1. 演示

效果如下:

2. 实现过程

1. 先看下静态的扇形如何显示:

画板提供了arc() 函数来实现扇形区域:

object arc(real x, real y, real radius, real startAngle, real endAngle, bool anticlockwise)

以圆点(x, y)、半径 radius 的圆周上画弧, startAngle 和 endAngle都是从x轴开始以弧度测量的。以下为官方帮助文档的截图:

所以,我们先画一个最简单的扇形

Canvas{ ///画布
    id: _canvas
    width: 200
    height: 200
    anchors.margins: 50
    anchors.centerIn: parent
    contextType:  "2d";
    onPaint: {
        var ctx = getContext("2d");  ///画师
        ctx.fillStyle = "red"
        ctx.save();                 //ctx.save() 和 ctx.restore(); 搭配使用是清除画板的
        ctx.beginPath();
        //移动画笔到100,100位置
        ctx.moveTo(100,100);
        //原点在100,100,半径为100 ——> 起始度数为180  结束度数270
        ctx.arc(100, 100, 100, 180*Math.PI/180, 270 * Math.PI/180);
        ctx.closePath();
        ctx.fill()
        ctx.restore();
    }

运行如下:

2. 实现了一个扇形后,再实现多个扇形:

function paintPer(ctx,x,y, r, startAngle,endAngle, color) {
    ctx.fillStyle = color
    ctx.save();         //ctx.save() 和 ctx.restore(); 搭配使用是清除画板的
    ctx.beginPath();
    ctx.moveTo(x,y);
    ctx.arc(x,y,r,startAngle*Math.PI/180, endAngle*Math.PI/180);
    ctx.closePath();
    ctx.fill()
    ctx.restore();
}

onPaint: {
    var ctx = getContext("2d");  ///画师
    //外层底图
    paintPer(ctx,100,100,100,180,360,'grey')
    //外层动图:  angle就是显示的目标角度
    paintPer(ctx,100,100,100,180,angle,'black')
    //中间空白层
    paintPer(ctx,100,100,75,0,360,"white")
    //内层底图
    paintPer(ctx,100,100,66,180,360,'#EEE8CD')
    //内层动图 angle就是显示的目标角度
    paintPer(ctx,100,100,66,180,angle,'#EEB422')
    //内层空白层
    paintPer(ctx,100,100,63,0,360,"white")
}

如下:

3. 数据源:

//currentValue:   0%~100%
property real currentValue : 0
//angle:         180°~360°   //180°为100份
property real angle: (currentValue * 180 / 100 + 180)

Timer{
    id: timer
    interval: 20;
    running: true;
    repeat:     true;
    onTriggered: {
        if(currentValue === 100) {
            currentValue = 0;
        }
        currentValue += 1;
    }
}

完整代码

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 1.4

Window {
    id: root
    visible: true
    width: 400
    height: 200
    title: qsTr("Canvas For Sector")

    //currentValue:   0%~100%
    property real currentValue : 0
    //angle:         180°~360°   //180°为100份
    property real angle: (currentValue * 180 / 100 + 180)

    onCurrentValueChanged: _canvas.requestPaint();

    Canvas{ ///画布
        id: _canvas

        width: 200
        height: 200
        anchors.margins: 50
        anchors.centerIn: parent

        Timer{
            id: timer
            interval: 20;
            running: true;
            repeat:     true;
            onTriggered: {
                if(currentValue === 100) {
                    currentValue = 0;
                }
                currentValue += 1;
            }
        }

        contextType:  "2d";

        function paintPer(ctx,x,y, r, startAngle,endAngle, color) {

            ctx.fillStyle = color
            ctx.save();         //ctx.save() 和 ctx.restore(); 搭配使用是清除画板的
            ctx.beginPath();
            ctx.moveTo(x,y);
            ctx.arc(x,y,r,startAngle*Math.PI/180, endAngle*Math.PI/180);
            ctx.closePath();
            ctx.fill()
            ctx.restore();
        }

        onPaint: {
            var ctx = getContext("2d");  ///画师
            //外层底图
            paintPer(ctx,100,100,100,180,360,'grey')
            //外层动图:  angle就是显示的目标角度
            paintPer(ctx,100,100,100,180,angle,'black')
            //中间空白层
            paintPer(ctx,100,100,75,0,360,"white")
            //内层底图
            paintPer(ctx,100,100,66,180,360,'#EEE8CD')
            //内层动图 angle就是显示的目标角度
            paintPer(ctx,100,100,66,180,angle,'#EEB422')
            //内层空白层
            paintPer(ctx,100,100,63,0,360,"white")
        }

        //可以文字,可以图片
        Text {
            id: txt_progress
            anchors.bottom: parent.bottom
            anchors.bottomMargin: 100
            anchors.horizontalCenter: parent.horizontalCenter

            font.pixelSize: 26  //16
            font.bold:      true

            text: currentValue.toString() + "%"
            color: 'black'
        }
    }
}

GIT 工程文件点击这里:     QmlLearningPro编译选择 CanvasSector

QML 其它文章请点击这里:     QT QUICK QML 学习笔记

以上是关于Qt QML 基于画布的扇形的进度条(Canvas)的主要内容,如果未能解决你的问题,请参考以下文章

用canvas画布画一个圆形的进度条,里面的数字是模糊的怎么解决?谢谢

如何更改 QML Dial 中的圆形进度条?

前端扇形进度条怎么实现

如何在我的 C++ 代码中创建 QML 画布并在其上附加视频?比如Java Canvas我可以

持续时间长于更新时的 Qt 进度条动画

iOS圆环,环形渐变进度条的封装