项目需要做个水球状的百分比控件,因此用Canvas画了一个,原理比较简单,底层画一个正弦波,上面覆盖一个圆,然后两个图层Clip后即可得到需要的形状,效果图:
代码较为简单,该控件可修改前景色、背景色、球体边框颜色;可自定义是否开启水波动画等功能(水波动画由计时器重绘而成,讲究效率的代码中不建议开启,建议在数据改变时设置数值的方式添加动态效果),控件代码:
Percent.qml:
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.3
Item{
id:main
property real percent: 80 //百分比数值
property color borderColor:"#d2691e"//边框颜色
property color backgroundColor: "#00ffff" // 背景颜色
property color foregroundColor: "#ff69b4" //前景颜色
property bool animation: true
onPercentChanged: {
canvas.requestPaint()
}
Rectangle{
id:control
width: Math.min(parent.width,parent.height)
height: Math.min(parent.width,parent.height)
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
Canvas{
id:canvas
anchors.fill: parent
property real p: main.percent/100 //百分比
property real r: parent.width/2 //半径
property real d: 2*r //直径
property real j: 0 //动画位移
onPaint: {
var ctx = getContext("2d")
ctx.lineWidth = 2
ctx.save()
ctx.translate(parent.width/2,parent.height/2)
var y = r-p*d //波纹高度的Y
ctx.beginPath()
ctx.arc(0,0,r,0,2*Math.PI)
ctx.fillStyle = main.backgroundColor
ctx.fill()
ctx.strokeStyle = main.borderColor
ctx.stroke()
ctx.clip()
ctx.beginPath()
ctx.moveTo(-r,y)
for(var i=0;i<r*2;i++){
ctx.lineTo(-r+i,y+18*Math.sin((i+j)*Math.PI/180+20*p*Math.PI))
}
ctx.lineTo(r,r)
ctx.lineTo(-r,r)
ctx.closePath()
ctx.fillStyle = main.foregroundColor
ctx.fill()
ctx.stroke()
ctx.restore()
}
}
Text {
id: text_value
color: "#f0fb37"
text: main.percent+'%'
font.bold: true
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
font.pointSize: 30
}
}
Timer{
repeat: true
interval: 10
running: main.animation
onTriggered: {
canvas.j = canvas.j+5
canvas.requestPaint()
}
}
}
main.qml:
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.3
Window {
id: window
visible: true
width: 600
height: 600
title: qsTr("PercentChart")
Percent {
id: main
anchors.bottomMargin: 40
anchors.fill: parent
percent: 75
animation: true
borderColor:"#d2691e"
backgroundColor: "#00ffff"
foregroundColor: "#ff69b4"
}
Slider {
id: slider
stepSize: 1
to: 100
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
anchors.bottomMargin: 0
value: main.percent
onValueChanged: {
main.percent = slider.value
}
}
}
DEMO下载地址:SinPlothttps://github.com/zjgo007/QmlDemo/tree/master/SinPlot
demo中的Percent.qml直接加载入工程,设置好属性就可使用。