前言
绘制简单的直线、矩形、椭圆等就不介绍了,毕竟那种东西就一个函数就能解决的问题,无非就是一些抗锯齿之类的细节,大家自行百度相关函数即可。提示:本篇直接讲绘任意图——画笔工具
一、事件重写
想要绘图,得知道落笔的位置,而这里不再教大家如何创建笔了,就拿基本QPen绘图。
bool event(QEvent *event) override;
为了方便,上面就写一个总事件函数。
二、记录坐标
1.定义成员,以记录坐标位置
QVector<QPoint> points;
为什么用QVector不用QList或者QPoint数组,看后面。
2.加入坐标
代码如下:
bool Widget::event(QEvent *event)
{
QMouseEvent *e = static_cast<QMouseEvent*>(event);
if(event->type()==QEvent::MouseMove){
this->points.append(e->pos());
this->update();
}
return QWidget::event(event);
}
就只是将·按住并移动·的坐标加入到数组中,没有任何别的代码。
3.绘画点数组
我们很容易想到下面这个函数,来将所有点画出来。
进入QPolygon
中,我们可以看到有这样一个构造函数,参数为QVector<QPoint> &points
来构建一个QPolygon
于是代码可以这样写:
(为了简洁,可以直接写在bool Widget::event(QEvent *event)
函数中)
if(event->type()==QEvent::Paint){
QPainter painter(this);
QPen pen(QColor(255,0,0));
pen.setWidth(3);
painter.setPen(pen);
painter.drawPoints(QPolygon(this->points));
}
鼠标稍微挪快,画出线的效果却是这样:(断断续续)
所以立刻想到画线,而非画点:
//于是注销掉画点的函数,加上下面这句
painter.drawLines(QPolygon(this->points));
效果如下:
我承认确实有点儿改观,但是这并非想象中的效果。
后来发现有这样一个函数:
painter.drawPolygon(QPolygon(this->points));
它是用来画多边形的,效果有我们想象中有偏差,不过却是很接近了,仔细看看,也就是鼠标按下的那个点与鼠标当前的点之间有一条连线,仅此而已。
这是因为画多边形,多边形是一个封闭图形,所以才这样设计,然而我们继续往下找,可以接着找到这样一个函数:
painter.drawPolyline(QPolygon(this->points));
画 “多边线” 这个函数完美的符合了我们的预期。
因为没有鼠标松开判断,所以认为两次画的线为同一条线,要改的画也简单,将QVector<QPoint>
改为二维数组,并且在鼠标松开时,结束此条线的记录,并且重绘函数里也要遍历数组,一根线一根线的画。
还是写一下吧:
//.h文件中增加(或修改成)下面两行
QVector<QVector<QPoint>> points;
QVector<QPoint> point;
//.cpp文件中
bool Widget::event(QEvent *event)
{
QMouseEvent *e = static_cast<QMouseEvent*>(event);
if(event->type()==QEvent::MouseMove){
this->point.append(e->pos());
this->update();
}
else if(event->type()==QEvent::MouseButtonRelease){
points.append(point);
point.clear();
}
if(event->type()==QEvent::Paint){
QPainter painter(this);
QPen pen(QColor(255,0,0));
pen.setWidth(3);
painter.setPen(pen);
painter.drawPolyline(QPolygon(point));
for(auto p:this->points){
painter.drawPolyline(QPolygon(p));
}
}
return QWidget::event(event);
}
效果如下:
代码较少,就不传github了。
手打不易,转发请标注原文链接,谢谢。