MJSSG 2023-08-24 14:17 采纳率: 100%
浏览 136
已结题

在QT实现画图功能中,如何选中已画出的图形并对其进行操作

在QT实现画图功能中,如何选中已画出的图形

以下为实现画图的大部分代码,可正常画出矩形、椭圆和直线,求如何选中已画出的图形,并可以选中单个图形修改属性(如边框颜色,填充颜色,线宽等)和移动选中的图形

container.h

    QVector<QRect> _line;               //直线容器
    QVector<QRect> _ellipse;            //椭圆容器
    QVector<QRect> _rects;              //矩形容器

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

container.cpp

    _lpress = false;  //鼠标按下标志
    _drawType = 0; //当前绘画类型标志
    _drag = 0; //拖拽标志
    _width = 1; //线宽
    _isfill = 0; //填充标志
    _color = QColor(Qt::black); //当前画笔颜色
    _fillcolor = QColor(Qt::white); //当前填充颜色
MainWindow.h
```c++
private:
    container cont;  //容器

protected:
    void paintEvent(QPaintEvent*);              //重载重绘函数
    void mousePressEvent(QMouseEvent*);         //重载鼠标按下函数
    void mouseReleaseEvent(QMouseEvent*);       //重载鼠标松开函数
    void mouseMoveEvent(QMouseEvent*);          //重载鼠标移动函数

public slots:
    void Line();      //直线
    void Rects();     //矩形
    void Ellipses();  //椭圆

MainWindow.cpp

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.at(c) == 2)  //矩形
        {
            p.drawRect(cont._rects.at(irect++));
        }
        else if (cont._shape.at(c) == 3)  //椭圆
        {
            p.drawEllipse(cont._ellipse.at(iellipse++));
        }
        else if (cont._shape.at(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);
}

void MainWindow::mousePressEvent(QMouseEvent* e)  //鼠标按下
{
    if (e->button() == Qt::LeftButton)  //左键按下
    {
        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);
            }
            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);
            }
            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);
        }

    }
}

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 == 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 == 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::Rects()
{
    cont._drawType = 2;  //矩形
    cont._drag = 0;
}

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


  • 写回答

14条回答 默认 最新

  • 凤曦若兮 2023-08-30 14:48
    关注

    以下为改后的具体代码

    
    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++;
                }
                if (cont._selectedShapeIndex == c)  // 如果是选中的图形,则使用不同的样式绘制
                {
                    // 绘制选中图形的样式
                    QPen selectedPen(Qt::red, pen.width(), Qt::DashLine);
                    p.setBrush(Qt::NoBrush);
                    p.setPen(selectedPen);
                    if(cont._shape[c] == 2)
                    {
                        p.drawRect(cont._rects.at(cont._Rect));
                    }
                    else if(cont._shape[c] == 3)
                    {
                        p.drawEllipse(cont._ellipse.at(cont._Ellips));
                    }
                    else if(cont._shape[c] == 4)
                    {
                        p.drawLine(cont._line.at(cont._Line).topLeft(), cont._line.at(cont._Line).bottomRight());
                    }
                }
        }
    
        p.end();
        p.begin(this);
        p.drawPicture(0,0,pic);
        if(cont._save)
        {
            pic.save(cont.FileName);
        }
        if(cont._read)
        {
            pic.load(cont._FileName);
            p.drawPicture(0,0,pic);
        }
    }
    
    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);
                }
                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);
                }
                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);
            }
    
            else if (cont._drawType == 5)  //选择
            {
                cont._lpress = true;
                // 添加选中图形的操作
                if (e->button() == Qt::LeftButton)
                {
                    selectShape(e->pos());
                }
            }
            else if (cont._drawType == 6)  //选择移动
            {
                cont._lpress = true;
                // 添加选中图形的操作
                if (e->button() == Qt::LeftButton)
                {
                    selectShape(e->pos());
                }
            }
    
        }
    
    }
    
    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();
            }
            else if(cont._drawType == 5)   //选择
            {
                // 如果有选中的图形,则进行移动操作
                if (cont._selectedShapeIndex != -1)
                {
                    if (cont._shape[cont._selectedShapeIndex] == 2)  // 矩形
                    {
                        cont._rects[cont._Rect].moveCenter(e->pos());
                    }
                    else if (cont._shape[cont._selectedShapeIndex] == 3)  // 椭圆
                    {
                        cont._ellipse[cont._Ellips].moveCenter(e->pos());
                    }
                    else if (cont._shape[cont._selectedShapeIndex] == 4)  // 直线
                    {
                        QPoint delta = e->pos() - cont._line[cont._Line].topLeft();
                        cont._line[cont._Line].translate(delta);
                    }
                    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;
            }
            else if (cont._drawType == 5)  //选择
            {
                cont._lpress = false;  //松开标志
    
                if (e->button() == Qt::LeftButton)
                {
                    cont._selectedShapeIndex = -1;
                    cont._Rect = -1;
                    cont._Ellips = -1;
                    cont._Line = -1;
                    update(); // 重新绘制,取消选中状态
                }
            }
            else if (cont._drawType == 6)  //选择移动
            {
                cont._lpress = false;  //松开标志
    
                if (e->button() == Qt::LeftButton)
                {
    
                    if(cont._selectedShapeIndex != -1)
                    {
                        Move();
    
                        cont._natureSelect = cont._selectedShapeIndex;
                        cont._natureRect = cont._Rect;
                        cont._natureEllips = cont._Ellips;
                        cont._natureLine = cont._Line;
    
                        cont._selectedShapeIndex = -1;
                        cont._Rect = -1;
                        cont._Ellips = -1;
                        cont._Line = -1;
                        update(); // 重新绘制,取消选中状态
    
                    }
    
                }
    
    
            }
        }
    }
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(13条)

报告相同问题?

问题事件

  • 系统已结题 9月7日
  • 已采纳回答 8月30日
  • 创建了问题 8月24日

悬赏问题

  • ¥15 有偿求苍穹外卖环境配置
  • ¥15 代码在keil5里变成了这样怎么办啊,文件图像也变了,
  • ¥20 Ue4.26打包win64bit报错,如何解决?(语言-c++)
  • ¥15 clousx6整点报时指令怎么写
  • ¥30 远程帮我安装软件及库文件
  • ¥15 关于#自动化#的问题:如何通过电脑控制多相机同步拍照或摄影(相机或者摄影模组数量大于60),并将所有采集的照片或视频以一定编码规则存放至规定电脑文件夹内
  • ¥20 深信服vpn-2050这台设备如何配置才能成功联网?
  • ¥15 Arduino的wifi连接,如何关闭低功耗模式?
  • ¥15 Android studio 无法定位adb是什么问题?
  • ¥15 C#连接不上服务器,