龙空技术网

Qt Quick之Canvas

C加加Qt技术开发老杰 128

前言:

现在各位老铁们对“canvas刷新重绘问题”可能比较讲究,小伙伴们都需要了解一些“canvas刷新重绘问题”的相关资讯。那么小编也在网络上网罗了一些有关“canvas刷新重绘问题””的相关文章,希望小伙伴们能喜欢,咱们一起来学习一下吧!

 QML中的Canvas,俗称画布,它用来定义一个绘图区域,可以使用ECMAScript代码来绘制直线,矩形,贝塞尔曲线,弧线,图片,文字等图元,还可以为这些图元应用填充颜色和边框颜色,甚至还可以进行低阶的像素级的操作。

1. 几个重要概念

(1)画布

  下面的代码定义了一个宽320像素高240像素的画布

Canvas{    width:320;    height:240;}

(2)画师

  画师如同MFC中的DC和Qt C++中的QPainter,那么QML中的画师是谁呢?Content2D是也!可以在Qt帮助文档中使用索引模式查找“Context2D”关键字来查看相关信息。

文章最后为大家准备了Qt资料

↡↡↡↡↡↡↡↡↡↡↡↡↡↡↡↡↡↡↡↡↡↡↡↡↡↡↡↡

  方法1: 

Canvas{    onPaint:        {        var ctx = getContext("2d");    }}

  方法2:

Canvas{    id:canvas;    contextType:"2d";    onPaint:{        context.lineWidth=2;    }}

(3)画笔

  lineWidth:设置画笔的宽度

  strokeStyle:设置画笔颜色或风格

(4)画刷

  在context2D这里,fillStyle属性是描述画刷的

(5)坐标系

  (0,0)为左上角,x轴水平向右为正,y轴垂直向下为正

(6)图元

  基本图元有线,弧,矩形,曲线,文本,图片等

2. 基本绘图模式

 Canvas    {        width:400;        height:240;        onPaint:        {            var ctx = getContext("2d");            ctx.lineWidth = 2;  // 设置画笔宽度            ctx.strockStyle="red"; // 设置画笔颜色            ctx.fillStyle="blue"; // 设置填充色            ctx.beginPath();            ctx.rect(100,80,120,80);            ctx.fill();            ctx.stroke();        }    }

  上面代码演示如何绘制一个矩形和矩形边框,展示了使用Canvas和Context2D绘图的一般步骤:

(1)定义一个Canvas对象,设置width和Height

(2)定义onPaint信号处理器

(3)获取Context2D对象

(4)实际的绘图操作

3. 绘制路径

  使用Content2D绘制路径的一般步骤:

(1)调用beginPath()

(2)调用moveTo(),lineTo(),rect(),quadraticCurveTo(),arc(),bezierCurveTo()等可以构造路径元素的方法

(3)调用fill()或stroke()

  这里主要介绍下fillStyle属性的使用,fillStyle与Qt C++中的QBrush类似,保存用于填充图元的画刷,它可以是一个颜色值,也可以是CanvasGradient或CanvasPattern对象

Canvas    {        width: 400;        height: 240;        contextType:"2d";        onPaint:        {            var ctx = getContext("2d");            ctx.lineWidth = 2;            ctx.lineJoin = "round"            ctx.strokeStyle = "red";            ctx.font = "42px sans-serif";            //ctx.fillStyle = "blue"; // 使用颜色进行填充            var gradient = ctx.createLinearGradient(100,80,220,160);            gradient.addColorStop(0, Qt.rgba(255,255,255,1));            gradient.addColorStop(1, Qt.rgba(0,0,0,1));            ctx.fillStyle =gradient; // 使用渐变对象进行填充            ctx.beginPath();            ctx.moveTo(240,80);            ctx.lineTo(300,90);            ctx.rect(100,80,250,150);            ctx.text("stroke text", 110,120);            ctx.fill();            ctx.stroke();        }    }

  注意:closePath()方法用于结束当前的路径,从路径终点到起点绘制一条直线来封闭路径,比如:

ctx.beginPath();ctx.moveTo(100,80);ctx.lineTo(100,200);ctx.lineTo(300,200);ctx.closePath();ctx.fill();ctx.stroke();

  通过closePath绘制一个三角形

4. 绘制文本

Context2D对象与文本相关的方法有三个:fillText(),strokeText(),text()

fillText()使用fillStyle填充文字

strokeTexr()使用strokeStyle描文字边框

text()方法在路径上添加一串文本作为构成路径的元素之一

上面代码效果:

5. 绘制图片

  Context2D有4种不同形式的drawImage()方法,可以用来绘制图片

(1)显示本地图片

(2)显示网络图片

Canvas    {        width: 600;        height: 600;        id:canvas;        property var imageName: "dartlike_weapon.png";        property var imageUrl: ";;        onPaint:        {            var ctx = getContext("2d");            ctx.drawImage(imageUrl, 200,0); // 绘制网络图片            ctx.drawImage(imageName, 0,200);   // 绘制本地图片        }        Component.onCompleted:        {            loadImage(imageUrl);  // 异步加载图片,图片加载完发射imageLoaded信号            loadImage(imageName);        }        onImageLoaded:        {            requestPaint();  // 重绘Canvas        }    }

  上面的代码演示了显示本地和网络图片,Component.onCompleted附加信号处理器内调用Canvas的loadImage()方法来加载图片,该方法会异步加载图片,当图片加载完成时,发射imageLoaded信号,在对应的信号处理器onImageLoaded内调用requestPainte()方法来重回Canvas.怎样知道图片是否加载成功了呢?可以通过Canvas的isImageError(),isImageLoaded()两个方法来判断,他们接受和loadImage()同样的参数,返回布尔值,只有成功加载的图片才可以使用Context2D来绘制。

(3)使用Image属性显示网络图片

    Image        {            id:imageSource;            source: ";;            visible: false;            onStateChanged: {                if(status == Image.Ready)                {                    canvas.requestPaint();                }            }        }

(4)使用createImageData显示图像

  drawImage还可以绘制CanvasImageData对象,CanvasImageData对象使用一维数组,按照RGBA的顺序来保存图像数据

    onPaint:        {            var ctx = getContext("2d");            if(imageData == null)            {                imageData = ctx.createImageData(120,100);                for (var i = 0;i < 48000;i+=4)                {                    imageData.data[i] = Math.floor(Math.random()*255);                    imageData.data[i+1] = Math.floor(Math.random()*255);                    imageData.data[i+2] = Math.floor(Math.random()*255);                    imageData.data[i+3] = 255;                }            }            ctx.drawImage(imageData,0,0);   // 绘制createImageData        }

(5)4种方法的综合实例

import QtQuick 2.9import QtQuick.Window 2.2Window {    visible: true    width: 800    height: 600    title: qsTr("Hello World")    Canvas    {        width: 600;        height: 600;        id:canvas;        property var imageName: "dartlike_weapon.png";        property var imageUrl: ";;        Image        {            id:imageSource;            source: ";;            visible: false;            /*onStateChanged: {                if(status == Image.Ready)                {                    canvas.requestPaint();                }            }*/        }        property var imageData: null;        onPaint:        {            var ctx = getContext("2d");            if(imageData == null)            {                imageData = ctx.createImageData(120,100);                for (var i = 0;i < 48000;i+=4)                {                    imageData.data[i] = Math.floor(Math.random()*255);                    imageData.data[i+1] = Math.floor(Math.random()*255);                    imageData.data[i+2] = Math.floor(Math.random()*255);                    imageData.data[i+3] = 255;                }            }            ctx.drawImage(imageData,0,0);   // 绘制createImageData            ctx.drawImage(imageUrl, 200,0); // 绘制网络图片            ctx.drawImage(imageSource, 200,200); // 绘制image属性            ctx.drawImage(imageName, 0,200);   // 绘制本地图片        }        Component.onCompleted:        {            loadImage(imageUrl);  // 异步加载图片,图片加载完发射imageLoaded信号            loadImage(imageName);            loadImage(imageSource);        }        onImageLoaded:        {            requestPaint();  // 重绘Canvas        }    }}

Qt开发学习路线:Qt开发技术栈

Qt资料领取:「链接」

标签: #canvas刷新重绘问题