QML Canvas 简单电子白板

需求:

使用QML 自带的webView 来展示试题,需要再其基础上 进行简单的标注

 

效果:

 

源码:

import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick 2.7
import QtQuick.Controls 2.3

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


    Button{
        width: 32
        height: 32
        anchors.left: parent.left

    }

    Canvas {
        id: canvas
        anchors {
            left: parent.left
            right: parent.right
            top: parent.top //colorTools.bottom
            bottom: parent.bottom
            margins: 8
        }
        property real lastX
        property real lastY
        property color color: "red" // colorTools.paintColor
        property bool isEraser: false
        property int eraserRadius: 20

        onPaint: {
            var ctx = getContext('2d')
            if(canvas.isEraser){
                ctx.clearRect(lastX-10,lastY-30,40,40)
                lastX = area.mouseX
                lastY = area.mouseY

            }else{
                ctx.lineWidth = 4.0
                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
                if(canvas.isEraser){
                    defineCursor.visible=true
                    defineCursor.x=mouseX
                    defineCursor.y=mouseY-defineCursor.height/2

                    canvas.requestPaint()
                }else{
                    defineCursor.visible=false
                }
            }

            onReleased: {
                defineCursor.visible=false
            }
            onPositionChanged: {
                canvas.requestPaint()

                if(canvas.isEraser){
                    defineCursor.visible=true
                    defineCursor.x=mouseX
                    defineCursor.y=mouseY-defineCursor.height/2
                }else{
                    defineCursor.visible=false
                }
            }
        }

    }


    Row{
        id:rowBut
        anchors.bottom: parent.bottom
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.bottomMargin: 10

        Loader{
            id:selectL
            width: 64
            height: 64
            sourceComponent: btnCom
            Component.onCompleted: {
                item.text="选择"
                item.iconUrlClicked = "qrc:/images/Select (1).png"
                item.iconUrlUnClicked = "qrc:/images/Select.png"
                item.siClick.connect(function(){
                    penL.item.reset()
                    eraserL.item.reset()

                    canvas.isEraser=false
                    canvas.visible=false
                })

                item.click()
            }
        }

        Loader{
            id:penL
            width: 64
            height: 64
            sourceComponent: btnCom
            Component.onCompleted: {
                item.text="笔"
                item.iconUrlClicked = "qrc:/images/pen (1).png"
                item.iconUrlUnClicked = "qrc:/images/pen.png"
                item.siClick.connect(function(){
                    selectL.item.reset()
                    eraserL.item.reset()
                    canvas.isEraser=false
                    canvas.visible=true
                })
            }
        }

        Loader{
            id:eraserL
            width: 64
            height: 64
            sourceComponent: btnCom
            Component.onCompleted: {
                item.text="橡皮"
                item.iconUrlClicked = "qrc:/images/eraser (1).png"
                item.iconUrlUnClicked = "qrc:/images/eraser.png"
                item.siClick.connect(function(){
                    selectL.item.reset()
                    penL.item.reset()
                    canvas.isEraser=true
                })
            }
        }
    }

    Component{
        id:btnCom
        Rectangle{
            id:btnRect
            width: 60
            height: 60
            color: "#7FFFFFFF"
            radius: 3
            property string text: ""
            property url iconUrlClicked: ""
            property url iconUrlUnClicked: ""
            property bool isClicked: false

            signal siClick()

            Column{
                anchors.centerIn: parent
                Image {
                    width: 35
                    height: 35
                    source: btnRect.isClicked?btnRect.iconUrlClicked:btnRect.iconUrlUnClicked
                    anchors.horizontalCenter: parent.horizontalCenter
                }

                Text {
                    text: btnRect.text
                    anchors.horizontalCenter: parent.horizontalCenter
                    color: btnRect.isClicked?"white":"black"
                }
            }

            function reset(){
                btnRect.isClicked=false
                btnRect.color="#7FFFFFFF"
            }
            function click(){
                isClicked=!isClicked
                btnRect.siClick()
                if(isClicked)
                    btnRect.color="#30C361"
            }

            function hover(){
                if(isClicked)
                    return
                btnRect.color = "#E4E0DF"
            }

            function exit(){
                if(isClicked)
                    return
                btnRect.color="#7FFFFFFF"
            }
            MouseArea{
                anchors.fill: parent
                hoverEnabled: true
                onEntered: {
                    btnRect.hover()
                }

                onExited: {
                    btnRect.exit()
                }

                onClicked: {
                    btnRect.click()
                }
            }
        }
    }


    Image {
        id: defineCursor
        width: 40
        height: 40
        source: "qrc:/images/eraser.png"
        visible: false
    }
}

 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

土拨鼠不是老鼠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值