Qt QPainter鼠标绘制线条、矩形、多边形

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);
}
  • 5
    点赞
  • 65
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值