QT图形绘制(C++)【实现铅笔、直线、矩形、椭圆的绘制】

在QT中绘画首先需要创建QRect容器储存图形的属性,其次再QPainter创建画笔在QImage、QPixmap、QBitmap 和 QPicture中绘制

一、头文件

#include <QPainter>
#include <QRect>
#include <QColor>
#include <QVector>
#include <QPoint>

二、创建容器

(1)创建QRect容器储存直线、矩形、椭圆,vector<QPoint>容器储存铅笔

    QVector<int> _shape;                //全部容器
    QVector<QRect> _allShape;           //所有图形
    QVector<QVector<QPoint> > _pen;     //铅笔线容器
    QVector<QRect> _line;               //直线容器
    QVector<QRect> _ellipse;            //椭圆容器
    QVector<QRect> _rects;              //矩形容器

(2)创建线宽、画笔颜色、填充颜色等属性容器

    int _width;                         //当前线宽
    QVector<int> _widths;               //线宽容器
    QVector<QColor> _colors;            //画笔颜色容器
    QVector<QColor> _fillcolors;        //填充色容器
    QVector<int> _isfills;              //填充标志容器
    int _isfill;                        //当前填充标志
    QColor _color;                      //当前画笔颜色
    QColor _fillcolor;                  //当前填充颜色

三、进行绘图

    QPoint _begin;                      //开始坐标
    bool_lpress = false;                        //鼠标按下标志
    int _drag = 0;                          //拖拽标志
    int _drawType = 0;                      //当前绘画类型标志

(1)进行对所绘制图形的选择

void MainWindow::Lines()
{
    cont._drawType = 1;  //铅笔
}
void MainWindow::Rects()
{
    cont._drawType = 2;  //矩形
    cont._drag = 0;
}

void MainWindow::Ellipses()
{
    cont._drawType = 3;  //椭圆
    cont._drag = 0;
}
void MainWindow::Line()
{
    cont._drawType = 4;  //直线
}

(2)绘制所选图形

对以下四个函数进行重载(paintEvent函数中可使用不同的类进行图像处理)

void MainWindow::mousePressEvent(QMouseEvent* e)  //鼠标按下
{
    if (e->button() == Qt::LeftButton)  //左键按下
    {
        if (cont._drawType == 1)  //铅笔
        {
            cont._lpress = true;  //按下标志为真

            QVector<QPoint> line;  //新铅笔线写入容器
            cont._pen.append(line);
            QVector<QPoint>& lastLine = cont._pen.last();

            lastLine.append(e->pos());  //新线条的开始坐标

            cont._colors.append(cont._color);  //记录各种状态
            cont._fillcolors.append(Qt::black);
            cont._isfills.append(0);
            cont._widths.append(cont._width);
            cont._shape.append(1);
        }
        else if (cont._drawType == 2)  //矩形
        {
            cont._lpress = true;
            if (!cont._drag)  //非拖拽
            {
                QRect rect;
                cont._rects.append(rect);
                QRect& lastRect = cont._rects.last();

                lastRect.setTopLeft(e->pos());

                cont._colors.append(cont._color);
                cont._fillcolors.append(cont._fillcolor);
                cont._isfills.append(cont._isfill);
                cont._widths.append(cont._width);
                cont._shape.append(2);
                cont._allShape.append(cont._rects.last());
            }
            else if (cont._rects.last().contains(e->pos()))  //拖拽,鼠标在图形内部
            {
                cont._begin = e->pos();  //记录起始的坐标
            }
        }
        else if (cont._drawType == 3)  //椭圆
        {
            cont._lpress = true;
            if (!cont._drag)
            {
                QRect rect;
                cont._ellipse.append(rect);
                QRect& lastEllipse = cont._ellipse.last();
                lastEllipse.setTopLeft(e->pos());
                cont._colors.append(cont._color);
                cont._fillcolors.append(cont._fillcolor);
                cont._isfills.append(cont._isfill);
                cont._widths.append(cont._width);
                cont._shape.append(3);
                cont._allShape.append(cont._ellipse.last());
            }
            else if (cont._ellipse.last().contains(e->pos()))
            {
                cont._begin = e->pos();
            }
        }
        else if (cont._drawType == 4)  //直线
        {
            cont._lpress = true;
            QRect rect;
            cont._line.append(rect);
            QRect& lastLine = cont._line.last();

            lastLine.setTopLeft(e->pos());

            cont._colors.append(cont._color);
            cont._fillcolors.append(Qt::black);
            cont._isfills.append(0);
            cont._widths.append(cont._width);
            cont._shape.append(4);
            cont._allShape.append(cont._line.last());
        }

    }

}
void MainWindow::mouseMoveEvent(QMouseEvent* e)  //鼠标移动
{
    if (cont._drag && ((cont._drawType == 2 && cont._rects.last().contains(e->pos())) ||
                       (cont._drawType == 3 && cont._ellipse.last().contains(e->pos()))))  //拖拽中
    {
        setCursor(Qt::SizeAllCursor);  //设置十字光标
    }
    else
    {
        setCursor(Qt::ArrowCursor);  //恢复原始光标形状
        cont._drag = 0;
    }

    if (cont._lpress)
    {
        if (cont._drawType == 1)  //铅笔画线,下同
        {
            if (cont._pen.size() <= 0)  //容器非空
                return;

            QVector<QPoint>& lastLine = cont._pen.last();  //取得新线条
            lastLine.append(e->pos());                     //容器内存入线条轨迹
            update();                                      //更新画板
        }
        else if (cont._drawType == 2)  //矩形
        {
            if (cont._drag == 0)  //非拖拽
            {
                QRect& lastRect = cont._rects.last();
                lastRect.setBottomRight(e->pos());  //更新右下角坐标
            }
            else  //拖拽
            {
                QRect& lastRect = cont._rects.last();
                if (lastRect.contains(e->pos()))  //在矩形的内部
                {
                    int dx = e->pos().x() - cont._begin.x();  //移动
                    int dy = e->pos().y() - cont._begin.y();
                    lastRect = lastRect.adjusted(dx, dy, dx, dy);  //更新位置
                    cont._begin = e->pos();                        //刷新拖拽点起始坐标
                }
            }
            update();
        }
        else if (cont._drawType == 3)  //椭圆
        {
            if (cont._drag == 0)
            {
                QRect& lastEllipse = cont._ellipse.last();  //拿到椭圆
                lastEllipse.setBottomRight(e->pos());       //更新椭圆右下角坐标
            }
            else
            {
                QRect& lastEllipse = cont._ellipse.last();
                if (lastEllipse.contains(e->pos()))
                {
                    int dx = e->pos().x() - cont._begin.x();  //移动
                    int dy = e->pos().y() - cont._begin.y();
                    lastEllipse = lastEllipse.adjusted(dx, dy, dx, dy);
                    cont._begin = e->pos();
                }
            }
            update();
        }
        else if (cont._drawType == 4)  //直线
        {
            QRect& lastLine = cont._line.last();
            lastLine.setBottomRight(e->pos());
            update();
        }
    }
}
void MainWindow::mouseReleaseEvent(QMouseEvent* e)  //鼠标松开
{
    if (cont._lpress)
    {
        if (cont._drawType == 1)  //铅笔线
        {
            QVector<QPoint>& lastLine = cont._pen.last();
            lastLine.append(e->pos());  //记录线条的结束坐标
            cont._lpress = false;       //标志左键释放
        }
        else if (cont._drawType == 2)  //矩形
        {
            QRect& lastRect = cont._rects.last();
            if (!cont._drag)  //非拖拽
            {
                lastRect.setBottomRight(e->pos());  //更新右下角坐标

                this->cursor().setPos(this->cursor().pos().x() - lastRect.width() / 2,
                                      this->cursor().pos().y() - lastRect.height() / 2);  //光标置图形中心
                cont._drag = 1;                                                           //拖拽标志
            }
            cont._lpress = false;  //松开标志
        }
        else if (cont._drawType == 3)  //椭圆
        {
            QRect& lastEllipse = cont._ellipse.last();
            if (!cont._drag)
            {
                lastEllipse.setBottomRight(e->pos());

                this->cursor().setPos(this->cursor().pos().x() - lastEllipse.width() / 2,
                                      this->cursor().pos().y() - lastEllipse.height() / 2);
                cont._drag = 1;
            }
            cont._lpress = false;
        }
        else if (cont._drawType == 4)  //直线
        {
            QRect& lastLine = cont._line.last();
            lastLine.setBottomRight(e->pos());
            cont._lpress = false;
        }

    }
}
void MainWindow::paintEvent(QPaintEvent*)  //重绘
{
    QPicture pic;
    QPainter p;
    p.begin(&pic);


    int ipen = 0, irect = 0, iellipse = 0, iline = 0;  //工具索引

        for (int c = 0; c < cont._shape.size(); ++c)  //循环重绘容器内所有项
        {
            QPen pen(QColor(cont._colors.at(c)));  //每次循环设置画笔
            pen.setWidth(cont._widths.at(c));      //线宽
            if (cont._isfills.at(c))               //填充
            {
                QBrush brush(QColor(cont._fillcolors.at(c)));
                p.setBrush(brush);
            }
            else
            {
                p.setBrush(QBrush(Qt::NoBrush));
            }
            p.setPen(pen);

            if (cont._shape[c] == 1)  //铅笔线
            {
                const QVector<QPoint>& line = cont._pen.at(ipen++);  //分段绘制铅笔线
                for (int j = 0; j < line.size() - 1; ++j) { p.drawLine(line.at(j), line.at(j + 1)); }
            }
            else if (cont._shape[c] == 2)  //矩形
            {
                p.drawRect(cont._rects.at(irect));
                irect++;
            }
            else if (cont._shape[c] == 3)  //椭圆
            {
                p.drawEllipse(cont._ellipse.at(iellipse));
                iellipse++;
            }
            else if (cont._shape[c] == 4)  //直线
            {
                p.drawLine(cont._line.at(iline).topLeft(), cont._line.at(iline).bottomRight());
                iline++;
            }
         }

    p.end();
    p.begin(this);
    p.drawPicture(0,0,pic);
}

(3)添加所绘制图形的属性

void MainWindow::ChoseWid()  //选线宽
{
    QInputDialog* inPut = new QInputDialog(this);
    cont._width = inPut->getInt(this, "输入线宽", "请输入线宽(1-50)", cont._width, 1, 50);
    //线宽对话框,1-50
}

void MainWindow::ChoseClr()  //选画笔颜色
{
    QColorDialog* colDig = new QColorDialog(this);  //颜色对话框
    colDig->setWindowTitle(QString("画笔颜色选择"));
    colDig->setGeometry(500, 300, 556, 428);
    cont._color = colDig->getColor();  //当前颜色
}

void MainWindow::ChosefilClr()  //选填充色
{
    QColorDialog* colDig = new QColorDialog(this);  //颜色对话框
    colDig->setWindowTitle(QString("填充颜色选择"));
    colDig->setGeometry(500, 300, 556, 428);
    cont._fillcolor = colDig->getColor();  //当前填充色
    cont._isfill = 1;                      //填充标志
}

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值