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

1. 几个重要概念

(1)画布

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

Canvas
{
width:;
height:;
}

(2)画师

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

  方法1: 

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

  方法2:

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

(3)画笔

  lineWidth:设置画笔的宽度

  strokeStyle:设置画笔颜色或风格

(4)画刷

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

(5)坐标系

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

(6)图元

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

2. 基本绘图模式

 Canvas
{
width:;
height:;
onPaint:
{
var ctx = getContext("2d"); ctx.lineWidth = ; // 设置画笔宽度
ctx.strockStyle="red"; // 设置画笔颜色
ctx.fillStyle="blue"; // 设置填充色 ctx.beginPath();
ctx.rect(,,,);
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: ;
height: ;
contextType:"2d";
onPaint:
{
var ctx = getContext("2d");
ctx.lineWidth = ;
ctx.lineJoin = "round"
ctx.strokeStyle = "red";
ctx.font = "42px sans-serif"; //ctx.fillStyle = "blue"; // 使用颜色进行填充
var gradient = ctx.createLinearGradient(,,,);
gradient.addColorStop(, Qt.rgba(,,,));
gradient.addColorStop(, Qt.rgba(,,,));
ctx.fillStyle =gradient; // 使用渐变对象进行填充 ctx.beginPath();
ctx.moveTo(,);
ctx.lineTo(,);
ctx.rect(,,,);
ctx.text("stroke text", ,);
ctx.fill(); ctx.stroke();
}
}

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

ctx.beginPath();
ctx.moveTo(,);
ctx.lineTo(,);
ctx.lineTo(,);
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: ;
height: ;
id:canvas;
property var imageName: "dartlike_weapon.png";
property var imageUrl: "http://g2.ykimg.com/0516000053548ED267379F510C0061FA"; onPaint:
{
var ctx = getContext("2d"); ctx.drawImage(imageUrl, ,); // 绘制网络图片 ctx.drawImage(imageName, ,); // 绘制本地图片
} 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: "http://g2.ykimg.com/0516000053548ED267379F510C0061FA";
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(,);
for (var i = ;i < ;i+=)
{
imageData.data[i] = Math.floor(Math.random()*);
imageData.data[i+] = Math.floor(Math.random()*);
imageData.data[i+] = Math.floor(Math.random()*);
imageData.data[i+] = ;
}
} ctx.drawImage(imageData,,); // 绘制createImageData
}

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

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

Qt Quick之Canvas的更多相关文章

  1. Qt Quick实现的涂鸦程序

    之前一直以为 Qt Quick 里 Canvas 才干够自绘.后来发觉不是,原来还有好几种方式都能够画图! 能够使用原始的 OpenGL(Qt Quick 使用 OpenGL 渲染).能够构造QSGN ...

  2. Qt Quick 与 QML语言(初学笔记1)

    Qt Quick Qt Quick是一些新的UI技术的集合,用来帮助开发者创建一种现在越来越多用于手机.多媒体播放器.机顶盒以及其他便携式设备上的直观的.现代的.流畅的用户界面.简单来说,Qt Qui ...

  3. qt quick中qml编程语言

    Qt QML 入门 — 使用C++定义QML类型 发表于 2013 年 3 月 11 日   注册C++类 注册可实例化的类型 注册不实例化的QML类型 附带属性 注册C++类 注册可实例化的类型 如 ...

  4. Qt Quick 简单介绍

    Qt Quick 是 Qt 提供的一种高级用户界面技术.使用它可轻松地为移动和嵌入式设备创建流畅的用户界面. 在 Android 设备上, Qt Quick 应用默认使用 OpenGL ES ,渲染效 ...

  5. Qt Quick 之 PathView 具体解释

    PathView ,顾名思义,沿着特定的路径显示 Model 内的数据. Model 能够是 QML 内建的 ListModel . XmlListModel ,也能够是在 C++ 中实现的 QAbs ...

  6. Qt Quick 常用元素:ComboBox(下拉列表) 与 ProgressBar(进度条)

    一.ComboBox ComboBox,即下拉列表框,由一个列表框和一个标签控件(或编辑控件)组成.ComboBox 的下拉列表是使用 Menu 实现的,列表内的每个条目对应一个 Menultem. ...

  7. Qt Quick 常用元素:RadioButton(单选框),CheckBox(复选框) 与 GroupBox(分组框)

    先介绍一下 ExclusiveGroup. ExclusiveGroup (互斥分组)本身是不可见元素,用于将若干个可选择元素组合在一起, 供用户选择其中的一个选项.你可以在 ExclusiveGro ...

  8. 《Qt Quick 4小时入门》学习笔记4

    http://edu.csdn.net/course/detail/1042/14806?auto_start=1 Qt Quick 4小时入门 第七章:处理鼠标与键盘事件 1.处理鼠标事件 鼠标信号 ...

  9. 《Qt Quick 4小时入门》学习笔记3

    http://edu.csdn.net/course/detail/1042/14807?auto_start=1 Qt Quick 4小时入门 第八章:Qt Quick中的锚(anchors)布局 ...

随机推荐

  1. Struts2+hibernate+spring 配置事物

    今天自信看了看hibernate的事物配置问题,转载了其他人的日志,仅用来学习. struts+hibernate+spring事务配置 (2009-01-14 21:49:47) 转载▼ 标签: i ...

  2. Boxes and Candies(贪心)

    Boxes and Candies Time limit : 2sec / Memory limit : 256MB Score : 300 points Problem Statement Ther ...

  3. [原创]关于absolute、relative和float的一些思考

    absolute: 元素完全脱离文档流,不占文档流的位置,不使用top.left等属性时,仍然在原文档流位置上(但是不在文档流中,也不占用位置),设置了top.left等之后,向上寻找到第一个非sta ...

  4. jqcloud 标签云效果

    官网地址: http://mistic100.github.io/jQCloud/index.htmlgithub 地址: https://github.com/lucaong/jQCloud使用 & ...

  5. 记录-阿里云Oss文件上传

    public class OssUtil { /** * 上传图片 * @param file * @param request * @return */ public static Map<S ...

  6. [转]How Hash Algorithms Work

    来看看SHA-1到底是如何工作的 http://www.metamorphosite.com/one-way-hash-encryption-sha1-data-software

  7. Linux环境安装Nginx详细步骤

    1.yum解决编译nginx所需的依赖包,之后你的nginx就不会报错了yum install gcc patch libffi-devel python-devel  zlib-devel bzip ...

  8. 我的Android进阶之旅------> Android在TextView中显示图片方法

    面试题:请说出Android SDK支持哪些方式显示富文本信息(不同颜色.大小.并包含图像的文本信息),并简要说明实现方法. 答案:Android SDK支持如下显示富文本信息的方式. 1.使用Tex ...

  9. Swift学习 --- 2.1基础部分

    1.swift 能够省去; 2.println与print的差别就是一个能够换行一个不能够 3.swift省去了.h与.m 直接一个swift文件 4.元组能够返回多个值,元组(tuples)把多个值 ...

  10. oracle decode的用法

    需求:分别统计emp表中1980,1981,1982,1987年入职的同事的数量. 这里用decode很容易就解决了: select sum(t.num_1980) as "1980&quo ...