Qt通过鼠标绘制线条、矩形、多边形本质都是根据鼠标的坐标位移,使用QPainter的自带的函数进行绘制。具体代码如下:
graphicspainter.h
#ifndef GRAPHICSPAINTER_H
#define GRAPHICSPAINTER_H
#include <QWidget>
#include "shape.h"
#include "paintrectline.h"
class GraphicsPainter : public QWidget
{
Q_OBJECT
public:
explicit GraphicsPainter(QWidget *parent = nullptr);
void SetDraw(bool bDraw);
void SetCurrCode(Shape::Code);
signals:
void singalDrawOver();
public slots:
protected:
void paintEvent(QPaintEvent *); //绘制
void mousePressEvent(QMouseEvent *e); //按下
void mouseMoveEvent(QMouseEvent *e); //移动
void mouseReleaseEvent(QMouseEvent *e); //松开
void mouseDoubleClickEvent(QMouseEvent *event); //双击
bool bDraw; //是否处于绘制状态
bool bLeftClick; //是否已经开始左键点击,同时标识是否开始进行绘制
bool bMove; //是否处于绘制时的鼠标移动状态
bool bDoubleClick;
QVector<QPointF> pointList;
QPointF movePoint;
QPointF startPoint;
private:
Shape::Code currShapeCode;
Shape *shape;
bool perm;
QList<Shape*> shapeList;
};
#endif // GRAPHICSPAINTER_H
graphicspainter.cpp
GraphicsPainter::GraphicsPainter(QWidget *parent) : QWidget(parent),shape(nullptr)
{
//填充背景色
setAutoFillBackground(true);
setBackgroundRole(QPalette::Base);
setMouseTracking(true);
bDraw = false;
bLeftClick = false;
bMove = false;
SetDraw(true);
currShapeCode=Shape::Code::polygon;
SetCurrCode(currShapeCode);
}
void GraphicsPainter::SetDraw(bool bDraw)
{
this->bDraw = bDraw;
}
void GraphicsPainter::SetCurrCode(Shape::Code code)
{
this->currShapeCode=code;
switch(currShapeCode)
{
case Shape::Line:
{
shape = new Line;
break;
}
case Shape::Rect:
{
shape = new Rect;
break;
}
case Shape::polygon:
{
shape = new Polygon_;
break;
}
}
if(shape != NULL)
{
perm = false;
shapeList<<shape;
}
}
//重新实现paintEvent
void GraphicsPainter::paintEvent(QPaintEvent *)
{
QPainter painter(this);
if(bDraw)
{
// painter.setBrush(Qt::white);
// painter.drawRect(0, 0, size().width(), size().height());
//绘制出之前存在的图形
foreach(Shape * shape, shapeList)
{
shape->paint(painter);
}
//绘制当前的线条
if(shape)
{
shape->paint(painter);
}
}
}
//按下
void GraphicsPainter::mousePressEvent(QMouseEvent *event)
{
if(bDoubleClick)
{
bDoubleClick=false;
switch(currShapeCode)
{
case Shape::Line:
{
shape = new Line;
shape->setStart( event->pos());
shape->setEnd( event->pos());
break;
}
case Shape::Rect:
{
shape = new Rect;
shape->setStart( event->pos());
shape->setEnd( event->pos());
break;
}
case Shape::polygon:
{
shape = new Polygon_;
break;
}
}
if(shape != NULL)
{
perm = false;
shapeList<<shape;
}
}
if(bDraw) //绘制
{
if(!bLeftClick) //左键单击开始
{
bLeftClick = true;
startPoint= event->pos();
}
}
}
//移动
void GraphicsPainter::mouseMoveEvent(QMouseEvent *event)
{
if(bDraw&&bLeftClick)
{
switch(currShapeCode)
{
case Shape::Line: //划线
{
shape->setEnd( event->pos());
update();
break;
}
case Shape::Rect: //画矩形
{
shape->setEnd( event->pos());
update();
break;
}
case Shape::polygon: //画多边形
{
//movePoint = event->pos();
shape->setMovePoint(event->pos());
bMove = true;
shape->setMoveStatus(true);
this->update();
break;
}
}
}
}
//松开
void GraphicsPainter::mouseReleaseEvent(QMouseEvent *e)
{
if(bDraw&&bLeftClick)
{
shape->setPointF(QPointF(e->x(), e->y()));
bMove = false;
shape->setMoveStatus(false);
this->update();
}
}
//双击断开连接
void GraphicsPainter::mouseDoubleClickEvent(QMouseEvent *event)
{
if(bDraw)
{
bDoubleClick=true;
bLeftClick = false;
shape->setPointF(QPointF(startPoint.x(), startPoint.y()));
this->update();
singalDrawOver();
}
}
绘制图形的基类Shape.h
#ifndef SHAPE_H
#define SHAPE_H
#include <QtGui>
class Shape
{
public:
enum Code
{
Line,
Rect,
polygon
};
Shape();
void setStart(QPoint s);
void setEnd(QPoint e);
void setMovePoint(QPoint e);
void setPointF(QPointF point_);
QPoint startPoint();
QPoint endPoint();
void setMoveStatus(bool status);
virtual void paint(QPainter & painter) = 0;
protected:
QPoint start;
QPoint end;
QPoint movePoint;
QVector<QPointF> pointList;
bool move_status;
};
#endif // SHAPE_H
Shape.cpp
#include "shape.h"
Shape::Shape()
{
}
void Shape::setStart(QPoint s)
{
start = s;
}
void Shape::setEnd(QPoint e)
{
end = e;
}
void Shape::setMovePoint(QPoint e)
{
movePoint=e;
}
void Shape::setPointF(QPointF point_)
{
pointList.push_back(point_);
}
QPoint Shape::startPoint()
{
return start;
}
QPoint Shape::endPoint()
{
return end;
}
void Shape::setMoveStatus(bool status )
{
move_status=status;
}
具体绘制图形的子类paintrectline.h
#ifndef PAINTRECTLINE_H
#define PAINTRECTLINE_H
#include "shape.h"
class Line : public Shape
{
public:
Line();
void paint(QPainter &painter);
};
class Rect : public Shape
{
public:
Rect();
void paint(QPainter &painter);
};
class Polygon_: public Shape
{
public:
Polygon_();
void paint(QPainter &painter);
};
#endif // PAINTRECTLINE_H
#include "paintrectline.h"
Line ::Line()
{
}
void Line ::paint(QPainter &painter)
{
painter.drawLine(start, end);
}
Rect ::Rect()
{
}
void Rect ::paint(QPainter &painter)
{
painter.drawRect(start.x(), start.y(),end.x() - start.x(), end.y() - start.y());
}
Polygon_::Polygon_()
{
}
void Polygon_::paint(QPainter &painter)
{
painter.setPen(QColor(255,0,0));
QVector<QLineF> lines;
qDebug()<<"pointList.size()------"<<pointList.size();
for(int i = 0; i<pointList.size()-1; i++)
{
QLineF line(QPointF(pointList[i].x(), pointList[i].y()), QPointF(pointList[i+1].x(), pointList[i+1].y()));
lines.push_back(line);
}
//if(bMove&&pointList.size()>0)
if(move_status&&pointList.size()>0)
{
QLineF line(QPointF(pointList[pointList.size()-1].x(), pointList[pointList.size()-1].y()), movePoint);
lines.push_back(line);
}
painter.drawLines(lines);
}