上一篇:QPainter绘图工具的完善
文章目录
前言
开始添加路径移动(位置变换)功能,顺手改进前一次的简陋橡皮擦功能。(去掉功能很容易,改进才是思维的高光时刻)
一、橡皮擦功能思想(不过多介绍,带一笔)
上一次是直接在最终的容器image中(也可以说是图层)将像素点清除,而这一次的橡皮擦功能却和画笔功能一模一样,画笔是画有颜色的路径,而橡皮擦是画’清空’路径,所以这次的橡皮擦工具路径加入了栈中,能记录每次擦除的路径,撤回时能按路径撤回。
//画笔工具与橡皮工具的区别只有 一 行 代 码 。
.....
case 4: //画笔工具
path.lineTo(last); //记录在路径中
pointsNum++; //记录点的次数+1
if(pointsNum>255){ //每个路径记录了255个任意路径后便清零,保持绘画效率
drawPathtoDevice(&image,path);
paths.last().value().addPath(path);
path.clear();
path = QPainterPath(last); //重新定位到最后一个点,继续画
pointsNum=1; //重新记录点个数
}
break;
case 5: //橡皮工具
path.lineTo(last); //记录在路径中
pointsNum++; //记录点的次数+1
if(pointsNum>255){ //每个路径记录了255个任意路径后便清零,保持绘画效率
eraserPathfromDevice(&image,path);
paths.last().value().addPath(path);
path.clear();
path = QPainterPath(last); //重新定位到最后一个点,继续画
pointsNum=1; //重新记录点个数
}
break;
.....
二、路径移动
思想:判断鼠标点击时的坐标,与已入栈的路径对比,看是否在某条路径的范围内,而判断函数为:
上面这个函数是个坑,为QPainterPath类中的一个判断函数,用于判断某点或路径是否在该路径中。但是这个函数是以路径的边界作为一个矩形来判断的,也就是不包含边界值的判断,所以直线路径用这个函数无法判断某点是否在该直线之上。
我百度还百度不到问题,所以只能另求他法了,有幸,我找到下面这个函数。
代码如下(示例):
pressedshapeAndPathIndex=0;
for(shapeAndPath& sp:paths){
if(sp.value().controlPointRect().contains(pressPoint) && sp.key()!=5)
break;
pressedshapeAndPathIndex++;
}
//ShapeAndPath是自定义类,原型如下
class shapeAndPath{
private:
uint8_t n; //形状类型
QPainterPath path; //形状路径
public:
shapeAndPath(uint8_t n,QPainterPath path):n(n),path(path){}
int key(){return n;}
QPainterPath &value(){return path;}
};
PS:没有封装和完整的面向对象的思想,那么这个程序随着代码量的增加,编写起来的困难程度必定会呈指数般的倍增。
总结
用QPainter一般只绘画简单的图形,和做简单的位移变换,所以关于QPainter的教程就只写到这里。
若要绘制复杂的图形,和复杂的2D变换,则需要用到QGraphicsView
框架,它已经将所有的图形封装成了对象,并且对图形的移动、旋转、放缩等等都已经封装完善,创建后只需要简单调用即可,而不需要自己一个一个地去反复造轮子了。
项目地址如下:注释相对完整