写在前面
我觉得QT里面做可拖动图形,主要应该有两种方法,一种是将图形做成控件,直接就有现成的drop可以用,一种是在Canvas上画图,然后将每个图形保存下来,每次拖动都是重画,这两种方法说不上孰优孰劣,各有不同的长处,本篇介绍绘图法。
原理
假设我们有一个按钮,每按动一次就在画布上添加一个实心圆,现在我们要求在添加N个圆后能将某个圆拖动。原理:每次添加,都将圆的信息(坐标,大小等)记录进一个列表里,在每次重绘事件发生时(画布大小改变,拖动某个圆),都调用一个方法将列表遍历,将所有圆重画出来。
代码
话不多说上代码:
//drawmap.qml
import QtQuick 2.9
import QtQuick.Controls 2.5
import "paint.js" as Painter //将一些功能封装进js里面,稍后展示代码
Canvas {
id: mapdraw
anchors.fill: parent
//重绘事件发生时会调用onPaint(),这里是用于不使图形变形
onPaint: {
//将画笔和画布作为参数传递过去,传递可以酌情省略
Painter.setContext(mapdraw.getContext("2d"), mapdraw)
//重绘
Painter.drawCircles()
}
//放一个鼠标区域,相应鼠标事件
MouseArea {
id: mouseevent
anchors.fill: parent
//鼠标按下
onPressed: {
Painter.setContext(mapdraw.getContext("2d"), mapdraw)
//每次使用外部函数进行绘制前不要忘了这一句
mapdraw.requestPaint()
//这里是为了实现选取一个圆,鼠标坐标是为了计算鼠标是否在圆内
Painter.canvasClick(mouseX, mouseY)
}
//鼠标释放
onReleased: {
Painter.setContext(mapdraw.getContext("2d"), mapdraw)
mapdraw.requestPaint()
//停止拖动
Painter.stopDragging()
}
//这个槽默认状态下意思是鼠标既按下又拖动,可以设置为不按下就拖动
onPositionChanged: {
Painter.setContext(mapdraw.getContext("2d"), mapdraw)
mapdraw.requestPaint()
//拖动圆
Painter.dragCircle(mouseX, mouseY)