Qt-quick(qml) Canvas用法及鼠标绘制图形

Canvas

画布元素(canvas element)的基本思想是使⽤⼀个2D对象来渲染路径。这个2D对象包括了必要的绘图函数,画布元素(canvas element)充当绘制画布。2D对象⽀持画笔,填充,渐变,⽂本和绘制路径创建命令。canvas项目允许绘制直线和曲线,简单和复杂的形状,图形以及参考的图形图像。它还可以添加文本,颜色,阴影,渐变和图案,并执行低级像素操作。canvas输出可以保存为图像文件或序列化为URL。

在QML中,画布元素(canvas element)充当了绘制的容器。2D绘制对象提供了实际绘制的⽅法。绘制需要在onPaint事件中完成以下代码创建一个Canvas项目,画一条直线。

        典型绘制命令调⽤如下:

                   1. 装载画笔或者填充模式            

                   2. 创建绘制路径

                   3. 使⽤画笔或者填充绘制路径

import QtQuick 2.9
import QtQuick.Window 2.2

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Canvas {
        id: mycanvas
        width: 100
        height: 200
        onPaint: {
            var ctx = getContext("2d");

            // setup the stroke
            ctx.strokeStyle = "red"

            // create a path
            ctx.beginPath()

            ctx.moveTo(50,50)
            ctx.lineTo(150,50)

            // stroke path
            ctx.stroke()
        }
    }
}

 在绘制矩形时,我们提供了⼀个便捷的接⼝,而不需要调⽤stroke或者fill来完成。

import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 1.4

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    //定位元素,画四个带颜色的正方形
    Row {
        id: colorTools
        anchors {
            horizontalCenter: parent.horizontalCenter
            top: parent.top
            topMargin: 8
        }

        property color paintColor: "#33B5E5"
        spacing: 4

        //清楚按钮
        Button {
            text: "Clear"
            onClicked: {
                canvas.clear()
            }
        }

        //绑定点击更换颜色
        Repeater {
            model: ["#33B5E5", "#99CC00", "#FFBB33", "#FF4444"]

            Rectangle {
                id: colorSquare;
                width: 48; height: 48
                color: modelData
                signal clicked
                property bool active: false
                border.color: active? "#666666" : "#f0f0f0"
                border.width: 2

                MouseArea {
                    id: area1
                    anchors.fill :parent
                    onClicked: {
                        colorTools.paintColor = color
                    }

                }
            }
        }
    }

    //画框
    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
        }

        property real lastX
        property real lastY
        property color color: colorTools.paintColor  //继承颜色

        //清除函数
        function clear() {
            var ctx = getContext('2d')
            ctx.reset();
            canvas.requestPaint();
        }

        onPaint: {
            var ctx = getContext('2d')
            ctx.lineWidth = 1.5
            ctx.strokeStyle = canvas.color
            ctx.beginPath()
            ctx.moveTo(lastX, lastY)
            lastX = area.mouseX
            lastY = area.mouseY
            ctx.lineTo(lastX, lastY)
            ctx.stroke()
        }

        MouseArea {
            id: area
            anchors.fill: parent
            onPressed: {
                canvas.lastX = mouseX
                canvas.lastY = mouseY
            }
            onPositionChanged: {
                canvas.requestPaint()
            }
        }
    }
}

 效果如下:

 

画布绘制(Canvas Paint) 

1. 在这个例⼦中我们将使⽤画布(Canvas)创建⼀个简单的鼠标绘制程序。

import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 1.4

Window{
    id: root
    width: 640
    height: 480
    visible: true

    //鼠标点击坐标位置
    property real startX     //储存鼠标开始时的坐标
    property real startY
    property real stopX      //储存鼠标结束时的坐标
    property real stopY

    //在root上画一个方框
    Rectangle{
        anchors.fill: canvas
        border.color: "#666"
        border.width: 4;
    }

    //创建一个画布
    Canvas{
        id:canvas;
        anchors.fill:parent

        onPaint: {
            var ctx = getContext("2d")
            ctx.lineWidtn = 3
            ctx.strokeStyle = "blue";

            //开始绘制
            ctx.beginPath()
            ctx.moveTo(startX,startY)

            //纪录鼠标开始的位置的坐标点
            startX = area.mouseX;
            startY = area.mouseY;
            ctx.lineTo(startX,startY)
            ctx.stroke()
        }

    }

    MouseArea{
        id:area;
        anchors.fill: parent;

        //当鼠标按下时调用本函数
        onPressed: {
            startX = mouse.x;
            startY = mouse.y;
            isMouseMoveEnable = true
        }

        //当鼠标释放时调用本函数
        onReleased: {
            isMouseMoveEnable = false
            canvas.requestPaint()      //当鼠标released时,调用绘制paint

        }

        //当鼠标press位置改变,调用本函数
        onPositionChanged: {
            if (isMouseMoveEnable){
                canvas.requestPaint()   //绘制函数
            }
        }
    }
}

效果如下:

 

 

对上述例子进行扩展:

import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 1.4

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Row {
        id: colorTools
        anchors {
            horizontalCenter: parent.horizontalCenter
            top: parent.top
            topMargin: 8
        }

        property color paintColor: "#33B5E5"
        spacing: 4

        Button {
            text: "Clear"
            onClicked: {
                canvas.clear()
            }
        }

        Repeater {
            model: ["#33B5E5", "#99CC00", "#FFBB33", "#FF4444"]

            Rectangle {
                id: colorSquare;
                width: 48; height: 48
                color: modelData
                signal clicked
                property bool active: false
                border.color: active? "#666666" : "#f0f0f0"
                border.width: 2

                MouseArea {
                    id: area1
                    anchors.fill :parent
                    onClicked: {
                        colorTools.paintColor = color
                    }

                }
            }
        }
    }

    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
        }

        property real lastX
        property real lastY
        property color color: colorTools.paintColor

        function clear() {
            var ctx = getContext('2d')
            ctx.reset();
            canvas.requestPaint();
        }

        onPaint: {
            var ctx = getContext('2d')
            ctx.lineWidth = 1.5
            ctx.strokeStyle = canvas.color
            ctx.beginPath()
            ctx.moveTo(lastX, lastY)
            lastX = area.mouseX
            lastY = area.mouseY
            ctx.lineTo(lastX, lastY)
            ctx.stroke()
        }

        MouseArea {
            id: area
            anchors.fill: parent
            onPressed: {
                canvas.lastX = mouseX
                canvas.lastY = mouseY
            }
            onPositionChanged: {
                canvas.requestPaint()
            }
        }
    }
}

效果如下:

 

2. 鼠标绘制长方形,无绘制轨迹

import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 1.4


Window{
    id: root
    width: 640
    height: 480
    visible: true

    //鼠标点击坐标位置
    property real startX     //储存鼠标开始时的坐标
    property real startY
    property real stopX      //储存鼠标结束时的坐标
    property real stopY
    property bool isMouseMoveEnable: false //是否允许鼠标移动绘制事件

    //在root上画一个方框
    Rectangle{
        anchors.fill: canvas
        border.color: "#666"
        border.width: 4;
    }

    //创建一个画布
    Canvas{
        id:canvas;
        anchors.fill:parent

        onPaint: {
            var ctx = getContext("2d")
            ctx.lineWidtn = 3
            ctx.strokeStyle = "blue";

            if (!isMouseMoveEnable) {
                ctx.clearRect(0,0,width,height) //清空所画图形
                return;
            }

            if (isMouseMoveEnable){
                ctx.clearRect(0,0,width,height)
            }

            //开始绘制
            ctx.beginPath()
            ctx.moveTo(startX,startY)

            //记录移动终点
            stopX = area.mouseX
            stopY = area.mouseY

            //绘制长方形
            ctx.strokeRect(startX,startY,stopX-startX,stopY-startY)
            ctx.stroke()
        }
    }

    MouseArea{
        id:area;
        anchors.fill: parent;

        //当鼠标按下时调用本函数
        onPressed: {
            startX = mouse.x;
            startY = mouse.y;
            isMouseMoveEnable = true
        }

        //当鼠标press位置改变,调用本函数
        onPositionChanged: {
            if (isMouseMoveEnable){
                canvas.requestPaint()   //绘制函数
            }
        }
    }
}

效果如下:

 

3. 鼠标释放长方形消失

import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 1.4


Window{
    id: root
    width: 640
    height: 480
    visible: true

    //鼠标点击坐标位置
    property real startX     //储存鼠标开始时的坐标
    property real startY
    property real stopX      //储存鼠标结束时的坐标
    property real stopY
    property bool isMouseMoveEnable: false //是否允许鼠标移动绘制事件

    //在root上画一个方框
    Rectangle{
        anchors.fill: canvas
        border.color: "#666"
        border.width: 4;
    }


    //创建一个画布
    Canvas{
        id:canvas;
        anchors.fill:parent

        onPaint: {
            var ctx = getContext("2d")
            ctx.lineWidtn = 3
            ctx.strokeStyle = "blue";


            if (!isMouseMoveEnable) {
                ctx.clearRect(0,0,width,height) //清空所画图形
                return;
            }

            if (isMouseMoveEnable){
                ctx.clearRect(0,0,width,height)
            }

            //开始绘制
            ctx.beginPath()
            ctx.moveTo(startX,startY)
            //console.log(startX,startY)

            //记录移动终点
            stopX = area.mouseX
            stopY = area.mouseY

            //绘制长方形
            ctx.strokeRect(startX,startY,stopX-startX,stopY-startY)
            ctx.stroke()
        }

    }

    MouseArea{
        id:area;
        anchors.fill: parent;

        //当鼠标按下时调用本函数
        onPressed: {
            startX = mouse.x;
            startY = mouse.y;
            isMouseMoveEnable = true
        }

        //当鼠标释放时调用本函数
        onReleased: {
            isMouseMoveEnable = false
            canvas.requestPaint()      //当鼠标released时,调用绘制paint

        }

        //当鼠标press位置改变,调用本函数
        onPositionChanged: {
            if (isMouseMoveEnable){
                canvas.requestPaint()   //绘制函数
            }
        }
    }
}

效果如下:

4. 有绘制轨迹的

 

import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 1.4


Window{
    id: root
    width: 640
    height: 480
    visible: true

    //鼠标点击坐标位置
    property real startX     //储存鼠标开始时的坐标
    property real startY
    property real stopX      //储存鼠标结束时的坐标
    property real stopY
    property bool isMouseMoveEnable: false //是否允许鼠标移动绘制事件

    //在root上画一个方框
    Rectangle{
        anchors.fill: canvas
        border.color: "#666"
        border.width: 4;
    }


    //创建一个画布
    Canvas{
        id:canvas;
        anchors.fill:parent

        onPaint: {
            var ctx = getContext("2d")
            ctx.lineWidtn = 3
            ctx.strokeStyle = "blue";

            //开始绘制
            ctx.beginPath()
            ctx.moveTo(startX,startY)
            //console.log(startX,startY)

            //记录移动终点
            stopX = area.mouseX
            stopY = area.mouseY

            //绘制长方形
            ctx.strokeRect(startX,startY,stopX-startX,stopY-startY)

            ctx.stroke()
        }

    }
    MouseArea{

        id:area;
        anchors.fill: parent;

        //当鼠标按下时调用本函数
        onPressed: {
            startX = mouse.x;
            startY = mouse.y;
            isMouseMoveEnable = true
        }

        //当鼠标press位置改变,调用本函数
        onPositionChanged: {
            if (isMouseMoveEnable){
                canvas.requestPaint()   //绘制函数
            }
        }
    }
}

效果如下:

 

扩展可以仿照前面的写,这里就不在叙述了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值