閱讀本文大概需要3分鐘
QML中繪圖方式有多種,Canvas(QML)是一種,當(dāng)然使用QQuickPaintedItem(C++實(shí)現(xiàn))也是可以的.
使用
Canvas繪圖核心部分如下所示:
Canvas{
id: vanvas
//畫布尺寸
width: 300
height: 300
onPaint: {
var ctx = getContext("2d")
//....下面需要調(diào)用js進(jìn)行繪圖
}
}
Canvas所有的繪圖都在onPaint中進(jìn)行,并且Canvas是透明的,默認(rèn)沒有背景色.
基本屬性
Canvas 就像一塊畫布,在某個(gè)范圍內(nèi)我們可以隨意進(jìn)行繪制。不要超過自己定義的畫布范圍哦,否則會(huì)出現(xiàn)一些Warning,親測(cè).
QSGThreadedRenderLoop: expose event received for window QQuickWindow(0x183a51a0)
with invalid geometry: QRect(533,219 140x0) on QScreen(0x3ed18, name=\\.\DISPLAY8)
- 畫布大小范圍
width: 300
height: 300
- 畫布對(duì)象
//方法原型
object getContext(string contextId, ... args)
//使用
var ctx = getContext("2d")
目前只支持 2d 類型,使用時(shí)直接傳遞2d參數(shù)即可.
剛看了下文檔,Qt5.10 有了3D類型了,Qt Canvas 3D,走的是WebGL方式,以后在研究……
- 坐標(biāo)系
Canvas 坐標(biāo)系和我們平時(shí)使用的基本一直,原點(diǎn)在左上角,水平向右為X軸,垂直向下為Y軸,單位都是像素

- 畫直線
//移動(dòng)到起點(diǎn)
ctx.moveTo(0,0)
//畫線
ctx.lineTo(200,200)
//描邊
ctx.stroke()
- 畫矩形
繪制矩形可以有兩種方式
1. 填充并繪制
2. 先繪制再填充
onPaint: {
var ctx = getContext("2d")
//設(shè)置填充顏色
ctx.fillStyle = "#19E5DF"
ctx.strokeStyle = "#F8B50D";
ctx.fillRect(10,10,100,100)
ctx.strokeRect(10,10,100,100)
}
如果沒有設(shè)置填充顏色,默認(rèn)會(huì)是黑色.
onPaint: {
var ctx = getContext("2d")
//設(shè)置填充顏色
ctx.fillStyle = "#19E5DF"
ctx.rect(20,10,180,180)
ctx.fillStyle = "#19E5DF"
ctx.stroke()
ctx.fill()
}
注:Canvas繪圖時(shí)填充和描邊是非常消耗資源的,一個(gè)節(jié)省資源提高效率的辦法就是先繪制好所有的路徑,最后一次性填充或者描邊.
例如上述繪制矩形方式2中就是先繪制路徑,最后填充.

- 畫圓
arc() 方法創(chuàng)建弧/曲線(用于創(chuàng)建圓或部分圓)
提示:如需通過 arc() 來創(chuàng)建圓,請(qǐng)把起始角設(shè)置為 0,結(jié)束角設(shè)置為 2Math.PI。*
提示:請(qǐng)使用 stroke() 或 fill() 方法在畫布上繪制實(shí)際的弧

中心:arc(100,75,50,0*Math.PI,1.5*Math.PI)
起始角:arc(100,75,50,0,1.5*Math.PI)
結(jié)束角:arc(100,75,50,0*Math.PI,1.5*Math.PI)
counterclockwise: False = 順時(shí)針,true = 逆時(shí)針。
- 畫曲線
函數(shù)原型
object arc(real x, real y, real radius, real startAngle, real endAngle, bool anticlockwise)
參數(shù) anticlockwise 表示是否是逆時(shí)針,默認(rèn)為false,即默認(rèn)順時(shí)針繪制!

var ctx = getContext("2d")
ctx.arc(100,100,50,0,Math.PI*2)
ctx.fill()
ctx.stroke()
}

貝賽爾曲線
一個(gè)控制點(diǎn)
object quadraticCurveTo(real cpx, real cpy, real x, real y)
兩個(gè)控制點(diǎn)
object bezierCurveTo(real cp1x, real cp1y, real cp2x, real cp2y, real x, real y)
x和y均為終點(diǎn)坐標(biāo)
繪制圖像
繪制圖像直接可以使用外部傳遞一個(gè)url,然后進(jìn)行加載,這也是比較常用的一種方法。
property var m_picturePath: "./Config/Skins/Default/Icons/head_picture.png"
Canvas
{
id: canvas
anchors.fill: parent
onPaint:
{
var ctx = canvas.getContext("2d");
ctx.drawImage(m_picturePath,0,0,width,height);
}
Component.onCompleted:
{
loadImage(m_picturePath)
}
onImageLoaded:
{
requestPaint();
//其他處理
}
}