作者: 狐狸家的鱼

Github: 八至

版权声明:如需转载请获取授权和联系作者

用纯qml实现canvas画板功能,用鼠标进行画图,可以画直线,画圆,画矩形,画弧线。

由于canvas画图会有延迟和卡顿,建议还是结合c++实现画图功能。

以下gif效果都没有录进鼠标

1.鼠标点击画图-无预览路径(两点实现)

贴上代码和注释:

    property real startX
property real startY
property real stopX
property real stopY
property color color: colorTools.paintColor
property var paintType: ["line","rect","circle","curve"]//自定义绘制类型
property var clickPoint: []//多边形画图的存点数组 未实现
property int clickNum: 0//鼠标点击 Row{
id:colorTools//颜色提取工具
anchors{
horizontalCenter: parent.horizontalCenter
top: parent.top
topMargin: 8 }
property color paintColor: "#33b5e5"//设置初始画笔颜色
spacing: 4;
// Repeater{//四个colorSquare
// model: ["#33B5E5", "#99CC00", "#FFBB33", "#FF4444"]//modelData 颜色数据
// ColorSquare{
// id:red;
// color: modelData;
// active: parent.paintColor == color//当选中一个colorSquare时,当前画笔颜色为选中的颜色
// onClicked: {
// parent.paintColor = color
// } // }
// }
Button {
text: "Clear"
onClicked: {
canvas.clear()
}
}
Button{
text: "line";
onClicked: { paintType = "line";
//canvas.requestPaint();
} }
Button{
text: "rect"
onClicked: {
paintType = "rect";
// canvas.requestPaint();
}
}
Button{
text: "circle"
onClicked: {
paintType = "circle";
// canvas.requestPaint();
}
}
Button{
text: "curve"
onClicked: {
paintType = "curve";
// canvas.requestPaint();
}
}
}
Rectangle{
anchors.fill: canvas
border.color: "#666"
border.width: 4; }
Canvas{
id:canvas;
anchors{
left: parent.left;
right:parent.right;
top:colorTools.bottom;
bottom: parent.bottom;
margins: 8
}
//鼠标点击坐标位置 function clear() {
var ctx = getContext("2d");
ctx.reset();
canvas.requestPaint();
}
onPaint: {
var ctx = getContext("2d")
ctx.lineWidtn = 5
ctx.strokeStyle = canvas.color;//轮廓颜色
//ctx.fillStyle = canvas.color;//填充颜色
ctx.beginPath()
if(paintType === "line"){
ctx.moveTo(startX,startY)
startX = area.mouseX;
startY = area.mouseY;
ctx.lineTo(stopX,stopY)
stopX = area.mouseX;
stopY = area.mouseY; }
if(paintType === "rect"){
//ctx.fillRect(startX,startY,stopX-startX,stopY-startY)//填充类型
//ctx.clearRect(0,0,width,height)
ctx.strokeRect(startX,startY,stopX-startX,stopY-startY)//非填充
}
if(paintType === "circle"){
ctx.arc(startX,startY,Math.sqrt(Math.pow((stopX-startX),2)+Math.pow((stopY-startY),2)),0,360,false)
}
if(paintType === "curve"){
ctx.arcTo(startX,startY,stopX,stopY,Math.sqrt(Math.pow((stopX-startX),2)+Math.pow((stopY-startY),2)))
} // ctx.fill();//完成填充
ctx.stroke()
}
MouseArea{
id:area;
anchors.fill: parent;
onClicked: {//存点 遍历
//clickPoint.push({"x":mouseX,"y":mouseY})//多边形绘制存点 多边形未实现
clickNum++;
for(var i = 0;i<clickPoint.length;i++){
var point = clickPoint[i]; } if(clickNum == 1){
startX = mouseX;
startY = mouseY;
}
if(clickNum == 2){
clickNum = 0;
stopX = mouseX;
stopY = mouseY;
canvas.requestPaint();
} }
} }
}

2.鼠标按压拖动绘图-无预览路径(鼠标释放完成绘制)

代码和注释:

    property real startX
property real startY
property real stopX
property real stopY
property color color: colorTools.paintColor
property var paintType: ["line","rect","circle","curve"]
property var clickPoint: []
property int clickNum: 0
Row{
id:colorTools//颜色提取工具
anchors{
horizontalCenter: parent.horizontalCenter
top: parent.top
topMargin: 8 }
property color paintColor: "#33b5e5"//设置初始画笔颜色
spacing: 4;
// Repeater{//四个colorSquare
// model: ["#33B5E5", "#99CC00", "#FFBB33", "#FF4444"]//modelData 颜色数据
// ColorSquare{
// id:red;
// color: modelData;
// active: parent.paintColor == color//当选中一个colorSquare时,当前画笔颜色为选中的颜色
// onClicked: {
// parent.paintColor = color
// } // }
// }
Button {
text: "Clear"
onClicked: {
canvas.clear()
}
}
Button{
text: "line";
onClicked: { paintType = "line";
//canvas.requestPaint();
} }
Button{
text: "rect"
onClicked: {
paintType = "rect";
// canvas.requestPaint();
}
}
Button{
text: "circle"
onClicked: {
paintType = "circle";
// canvas.requestPaint();
}
}
Button{
text: "curve"
onClicked: {
paintType = "curve";
// canvas.requestPaint();
}
}
}
Rectangle{
anchors.fill: canvas
border.color: "#666"
border.width: 4; }
Canvas{
id:canvas;
anchors{
left: parent.left;
right:parent.right;
top:colorTools.bottom;
bottom: parent.bottom;
margins: 8
}
//鼠标点击坐标位置 function clear() {//此清除有问题
var ctx = getContext("2d");
ctx.reset();
canvas.requestPaint();
}
onPaint: {
var ctx = getContext("2d")
ctx.lineWidtn = 10
ctx.strokeStyle = canvas.color;
// ctx.fillStyle = canvas.color;//若想要填充的 此不注释
ctx.beginPath()
if(paintType === "line"){
ctx.moveTo(startX,startY)
startX = area.mouseX;
startY = area.mouseY;
ctx.lineTo(stopX,stopY)
stopX = area.mouseX;
stopY = area.mouseY; }
if(paintType === "rect"){
//ctx.fillRect(startX,startY,stopX-startX,stopY-startY)//填充类型
//ctx.clearRect(0,0,width,height)
ctx.strokeRect(startX,startY,stopX-startX,stopY-startY)//非填充
}
if(paintType === "circle"){
ctx.arc(startX,startY,Math.sqrt(Math.pow((stopX-startX),2)+Math.pow((stopY-startY),2)),0,360,false)
}
if(paintType === "curve"){//未实现
ctx.arcTo(startX,startY,stopX,stopY,Math.sqrt(Math.pow((stopX-startX),2)+Math.pow((stopY-startY),2)))
} //ctx.fill();
ctx.stroke()
}
MouseArea{
id:area;
anchors.fill: parent;
// onClicked: {//存点 遍历
// clickPoint.push({"x":mouseX,"y":mouseY})
// clickNum++;
// for(var i = 0;i<clickPoint.length;i++){
// var point = clickPoint[i]; // } // if(clickNum == 1){
// startX = mouseX;
// startY = mouseY;
// }
// if(clickNum == 2){
// clickNum = 0;
// stopX = mouseX;
// stopY = mouseY;
// canvas.requestPaint();
// } // }
onPressed: {
startX = mouseX;
startY = mouseY;
} onMouseXChanged: {
stopX = mouseX;
}
onMouseYChanged: {
stopY = mouseY; }
onReleased: {
canvas.requestPaint()//重绘
} // onPositionChanged: {
// canvas.requestPaint()//重绘 这句话不注释 会有预览路径 但是临时区没有清理 需要在cpp中进行清除
// } } }

3.鼠标按压拖动绘制-有预览路径

因为想要绘制的过程中有预览路径,需要在cpp中实现清理临时区域,因为如果不清理 ,画直线的时候没问题,但是在画矩形圆的时候会出现如下情况:

cpp中如何画,可以参考这篇博文:https://blog.csdn.net/foruok/article/details/32698603

第三种方法可以在qml中有预览路径的同时也清理临时图区,只不过只能存在一个图元,也就是画了直线之后画圆,直线就会消失。所以还是建议结合c++中的QQuickPaintedItem方法等进行清理临时图区。这个链接有三个实例提供参考 https://www.aliyun.com/jiaocheng/173346.html ,上面那个链接就是对第一个实例的解释

以下代码我做了临时图元的简单清理,但是画线段的时候由于清理了,所以画不出来了,所以还是建议看博客结合cpp

通过gif可以看到录制把临时图元都看到了,但是在实际绘制的时候却看不到的,

QML学习笔记(二)-纯qml画图实现canvas画板-鼠标画图的更多相关文章

  1. qml学习笔记(二):可视化元素基类Item详解(上半场anchors等等)

    原博主博客地址:http://blog.csdn.net/qq21497936本文章博客地址:http://blog.csdn.net/qq21497936/article/details/78516 ...

  2. QML学习笔记(六)- 简单计时器和定时器

    做一个简单的qml计时器和定时器,左键触发计时,右键触发定时 GitHub:八至 作者:狐狸家的鱼 本文链接:QML学习笔记(六)- 简单计时器和定时器 左键点击按钮,触发计时器,中键可以暂停计时,同 ...

  3. QML学习笔记(五)— 做一个简单的待做事项列表

    做一个简单的QML待做事项列表,能够动态添加和删除和编辑数据 GitHub:八至 作者:狐狸家的鱼 本文链接:QML学习笔记(五)— 做一个待做事项列表 主要用到QML:ListView 效果 全部代 ...

  4. 纯JS实现KeyboardNav(学习笔记)二

    纯JS实现KeyboardNav(学习笔记)二 这篇博客只是自己的学习笔记,供日后复习所用,没有经过精心排版,也没有按逻辑编写 这篇主要是添加css,优化js编写逻辑和代码排版 GitHub项目源码 ...

  5. WPF的Binding学习笔记(二)

    原文: http://www.cnblogs.com/pasoraku/archive/2012/10/25/2738428.htmlWPF的Binding学习笔记(二) 上次学了点点Binding的 ...

  6. AJax 学习笔记二(onreadystatechange的作用)

    AJax 学习笔记二(onreadystatechange的作用) 当发送一个请求后,客户端无法确定什么时候会完成这个请求,所以需要用事件机制来捕获请求的状态XMLHttpRequest对象提供了on ...

  7. [Firefly引擎][学习笔记二][已完结]卡牌游戏开发模型的设计

    源地址:http://bbs.9miao.com/thread-44603-1-1.html 在此补充一下Socket的验证机制:socket登陆验证.会采用session会话超时的机制做心跳接口验证 ...

  8. JMX学习笔记(二)-Notification

    Notification通知,也可理解为消息,有通知,必然有发送通知的广播,JMX这里采用了一种订阅的方式,类似于观察者模式,注册一个观察者到广播里,当有通知时,广播通过调用观察者,逐一通知. 这里写 ...

  9. java之jvm学习笔记二(类装载器的体系结构)

    java的class只在需要的时候才内转载入内存,并由java虚拟机的执行引擎来执行,而执行引擎从总的来说主要的执行方式分为四种, 第一种,一次性解释代码,也就是当字节码转载到内存后,每次需要都会重新 ...

随机推荐

  1. Vue 刷新当前页面,并重新加载页面数据

    业务场景:在管理后台,在执行完,增,删,改,操作的时候.我们需要刷新一下页面,重载数据.在JQ中我们会用到location.reload()方法,刷新页面:在vue中,这里需要用到一个 provide ...

  2. dart正则

    1.前言 API中对于正则表达式的注释是:正则表达式的规范和语义与JavaScript相同详细的规范可以参考:http://ecma-international.org/ecma-262/5.1/#s ...

  3. js中获取当前项目名等

    实际上通过window.location可以获取很多跟资源路径相关的信息,需要用到的时候直接通过浏览器调试可以查看window.location的一些属性

  4. 运维常用mysql语句

    1..select @@version; ##查询当前mysql的版本. 2. show variables like 'port';##查看mysql实例的端口. 3.show variables ...

  5. 思维导图,UML图,程序流程图制作从入门到精通

    工具: https://www.processon.com/ 第一 用例图 第二 时序图 第三 流程图

  6. jquery和js的几种页面加载函数的方法以及执行顺序

    参考博客:http://www.cnblogs.com/itslives-com/p/4646790.html    https://www.cnblogs.com/james641/p/783837 ...

  7. 跳转语句之continue

    js里面有两个跳转语句,一个是continue,一个是break.由于这两个跳转语句都是用于循环当中,因此他们也就只能用于while.for.do…while语句中,当然了,break多加一个swit ...

  8. hdu-1814(2-sat)

    题意:给你n个组,m条规则,每组有俩个人,这两个人不能同时出现,然后m条规则代表着有两个人,这两个人也不能同时出现,问你是否存在每组都能出现一人的选择方案 解题思路:因为这个需要字典序输出,所以只能用 ...

  9. Linux下git的使用——将已有项目放到github上

    本地已经有一个项目了,需要将该项目放到github上,怎么操作? 步骤: 本地安装git,有github账号是前提. (1)先在github创建一个空的仓库,并复制链接地址.使用https,以.git ...

  10. Linux下的好用的编辑软件Remarkable

    Linux下的好用的编辑软件Remarkable最近着手开始学习Linux,就想着找一款好用的编辑器作笔记,在网上爬了些贴选择了Remarkable.官网崩了,有没有梯子,废了好大力气才装好.于是把资 ...