在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;  //直线
}


以下为改后的具体代码


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(); // 重新绘制,取消选中状态

                }

            }


        }
    }
}

记得是不行,但是可以改变思路,保留图形的原参数,重新绘制后刷新页面。

为了实现选中已画出的图形,并可以修改其属性和移动图形,您需要实现以下步骤:

  1. container.h中添加成员变量来跟踪选中的图形:
class container {
    // ...
private:
    int _selectedShape;  // 选中的图形索引
    bool _isSelected;    // 是否有图形被选中
};
  1. container.cpp中添加用于选中图形的函数:
void container::selectShape(const QPoint& point) {
    _isSelected = false;
    _selectedShape = -1;

    // 遍历图形并检查是否在点的范围内
    for (int i = 0; i < _rects.size(); ++i) {
        if (_rects.at(i).contains(point)) {
            _isSelected = true;
            _selectedShape = i;
            return;
        }
    }
    for (int i = 0; i < _ellipse.size(); ++i) {
        if (_ellipse.at(i).contains(point)) {
            _isSelected = true;
            _selectedShape = i;
            return;
        }
    }
    for (int i = 0; i < _line.size(); ++i) {
        if (_line.at(i).contains(point)) {
            _isSelected = true;
            _selectedShape = i;
            return;
        }
    }
}

void container::modifySelectedShape(const QColor& borderColor, const QColor& fillColor, int lineWidth) {
    if (_isSelected) {
        // 根据_selectedShape修改选中图形的属性
        // 您可以根据需要修改容器中的颜色、线宽等属性
    }
}

void container::moveSelectedShape(const QPoint& newPoint) {
    if (_isSelected) {
        // 根据_selectedShape移动选中的图形
        // 您可以根据需要修改容器中图形的坐标
    }
}
  1. MainWindow.cpp中重载鼠标按下、移动和松开事件来实现选中和移动图形:
void MainWindow::mousePressEvent(QMouseEvent* e) {
    if (e->button() == Qt::LeftButton) {
        // 选中图形
        cont.selectShape(e->pos());

        // ...
    }
}

void MainWindow::mouseMoveEvent(QMouseEvent* e) {
    // 移动选中的图形
    if (cont.isSelected()) {
        cont.moveSelectedShape(e->pos());
        update();
    }
    // ...
}

void MainWindow::mouseReleaseEvent(QMouseEvent* e) {
    // ...
    if (cont.isSelected()) {
        cont.modifySelectedShape(cont._color, cont._fillcolor, cont._width);
        cont.clearSelection();
        update();
    }
    // ...
}

这是一个基本示例,您需要根据实际需求进行调整和完善。通过在container中跟踪选中的图形索引和属性,您可以在画布上选中和修改已绘制的图形。同时,通过重载鼠标事件,您可以实现拖动选中的图形。

https://wenku.csdn.net/answer/4fa2ed34ad8f4012a72686d5bc71dfbd


Qt :QGraphicsScene管理QGraphicsItem(单击/选择/移动/缩放/删除)_闭上左眼看世界的博客-CSDN博客 本文转载大神作者:一去丶二三里 博客地址:http://blog.csdn.net/liang19890820.简述在图形视图框架中,QGraphicsScene 提供一个快速的接口,用于管理大量 item,QGraphicsItem 是场景中 item 的基类。图形视图提供了一些典型形状的标准 item,当然,我们也可以自定义 item。除此之外,QGraphicsItem 还支持以... https://blog.csdn.net/qq_37233607/article/details/79343891

该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索,得到内容具体如下:
要实现选中已画出的图形并对其进行操作,你需要进行以下步骤:

1、 在container.h中添加一个成员变量来跟踪选中的图形索引:

int _selectedShapeIndex;  // 选中的图形索引

2、 在MainWindow.h中添加一个成员函数来处理图形的选中操作:

void selectShape(const QPoint& point);  // 选择图形

3、 在MainWindow.cpp中实现selectShape函数:

void MainWindow::selectShape(const QPoint& point)
{
    for (int i = cont._shape.size() - 1; i >= 0; --i)  // 从后往前遍历图形容器,以便选择最上层的图形
    {
        if (cont._shape[i] == 2 && cont._rects[i].contains(point))  // 矩形
        {
            cont._selectedShapeIndex = i;  // 设置选中的图形索引
            return;
        }
        else if (cont._shape[i] == 3 && cont._ellipse[i].contains(point))  // 椭圆
        {
            cont._selectedShapeIndex = i;
            return;
        }
        else if (cont._shape[i] == 4 && cont._line[i].contains(point))  // 直线
        {
            cont._selectedShapeIndex = i;
            return;
        }
    }
    cont._selectedShapeIndex = -1;  // 如果没有选中任何图形,则将选中的图形索引设置为-1
}

4、 修改MainWindow::mousePressEvent函数,添加对图形的选中操作:

void MainWindow::mousePressEvent(QMouseEvent* e)
{
    if (e->button() == Qt::LeftButton)  // 左键按下
    {
        // ...

        if (cont._drawType == 2)  // 矩形
        {
            // ...
        }
        else if (cont._drawType == 3)  // 椭圆
        {
            // ...
        }
        else if (cont._drawType == 4)  // 直线
        {
            // ...
        }

        // 添加选中图形的操作
        if (cont._selectedShapeIndex == -1)  // 如果没有选中的图形,则尝试选中一个
        {
            selectShape(e->pos());
        }
        else  // 如果已经选中了一个图形,则取消选中该图形
        {
            cont._selectedShapeIndex = -1;
        }

        // ...
    }
}

5、 修改MainWindow::mouseMoveEvent函数,如果有选中的图形,则进行图形的移动操作:

void MainWindow::mouseMoveEvent(QMouseEvent* e)
{
    // ...

    if (cont._lpress)
    {
        // ...

        // 如果有选中的图形,则进行移动操作
        if (cont._selectedShapeIndex != -1)
        {
            if (cont._shape[cont._selectedShapeIndex] == 2)  // 矩形
            {
                cont._rects[cont._selectedShapeIndex].moveTopLeft(e->pos());
            }
            else if (cont._shape[cont._selectedShapeIndex] == 3)  // 椭圆
            {
                cont._ellipse[cont._selectedShapeIndex].moveTopLeft(e->pos());
            }
            else if (cont._shape[cont._selectedShapeIndex] == 4)  // 直线
            {
                QPoint delta = e->pos() - cont._line[cont._selectedShapeIndex].topLeft();
                cont._line[cont._selectedShapeIndex].translate(delta);
            }
            update();
        }
    }
}

6、 修改MainWindow::paintEvent函数,将选中的图形显示为不同的样式,以便区分:

void MainWindow::paintEvent(QPaintEvent*)
{
    // ...

    for (int c = 0; c < cont._shape.size(); ++c)
    {
        // ...

        if (c == cont._selectedShapeIndex)  // 如果是选中的图形,则使用不同的样式绘制
        {
            // 绘制选中图形的样式
            QPen selectedPen(Qt::red, pen.width(), Qt::DashLine);
            p.setPen(selectedPen);
            p.setBrush(Qt::NoBrush);
        }
    //请注意,以上只是一个基本的框架示例,你可能需要根据你的实际需求进行相应的调整和修改。另外,上述代码片段假设你已经有了合适的图形容器和相应的绘图代码。如果你还没有实现这些功能,你需要进一步完善代码以满足你的需求。

如果以上回答对您有所帮助,点击一下采纳该答案~谢谢

引用chatgpt内容作答:
在Qt中实现选中已绘制图形并对其进行操作的功能,你需要以下步骤:

1、添加选中图形的管理:

在你的container类中添加变量来追踪选中的图形索引和属性:

int _selectedShapeIndex;       // 选中的图形索引(-1表示未选中)
QColor _selectedBorderColor;   // 选中图形的边框颜色
QColor _selectedFillColor;     // 选中图形的填充颜色
int _selectedWidth;            // 选中图形的线宽

在构造函数中将_selectedShapeIndex初始化为-1。

2、修改绘图事件:

修改你的paintEvent函数来高亮选中的图形:

if (_selectedShapeIndex != -1) {
    QPen selectedPen(_selectedBorderColor);
    selectedPen.setWidth(_selectedWidth);
    p.setPen(selectedPen);
    p.setBrush(QBrush(_selectedFillColor));
    // 使用修改后的属性绘制选中的图形
    // ...
}

3、更新鼠标按下事件:

修改你的mousePressEvent函数来处理图形的选中:

if (e->button() == Qt::LeftButton) {
    // 倒序遍历图形(从上到下)
    for (int c = cont._shape.size() - 1; c >= 0; --c) {
        if (cont._rects.at(c).contains(e->pos()) ||
            cont._ellipse.at(c).contains(e->pos()) ||
            cont._line.at(c).contains(e->pos())) {
            _selectedShapeIndex = c;
            // 加载选中图形的属性
            _selectedBorderColor = cont._colors.at(c);
            _selectedFillColor = cont._fillcolors.at(c);
            _selectedWidth = cont._widths.at(c);
            break;
        }
    }
    update(); // 重新绘制,以突出显示选中的图形
}

4、更新鼠标移动事件:

修改你的mouseMoveEvent函数来处理选中图形的拖拽:

if (_selectedShapeIndex != -1) {
    QRect& selectedRect = cont._rects.at(_selectedShapeIndex);
    QRect& selectedEllipse = cont._ellipse.at(_selectedShapeIndex);
    QRect& selectedLine = cont._line.at(_selectedShapeIndex);

    // 根据拖拽更新图形的位置或属性
    // ...

    update(); // 重新绘制,以显示更新后的图形
}

5、更新鼠标释放事件:

当鼠标释放时,清除_selectedShapeIndex:

if (e->button() == Qt::LeftButton) {
    _selectedShapeIndex = -1;
    update(); // 重新绘制,取消选中状态
}

6、添加用户界面控件:

添加用户界面控件(按钮、颜色选择器等),以允许用户修改选中图形的属性。将这些控件连接到函数,这些函数将更新属性并触发重新绘制。

这只是一个基本的概述,根据你的实际需求和应用架构,你可能需要进一步调整。另外,考虑将与图形相关的数据和行为封装到类中,以使代码更有组织性和可维护性。

【以下回答由 GPT 生成】

对于实现选中已画出的图形并对其进行操作,你可以按照以下步骤进行:

  1. 在container.h文件中新增一个QRect selectedRect变量,用于保存当前选中的图形的边界矩形。 c++ QRect _selectedRect;

  2. 在container.cpp文件中,添加以下函数用于判断一个点是否在图形内部: c++ bool container::isPointInsideShape(const QPoint& point) { // 判断点是否在当前选中的图形内部,根据不同的图形类型使用不同的算法判断 // 返回true表示在图形内部,返回false表示不在图形内部 }

  3. 修改paintEvent函数,在绘制图形之前判断当前绘制的图形是否为选中的图形,如果是,则设置选中的图形的样式。 ```c++ void MainWindow::paintEvent(QPaintEvent*) { QPicture pic; QPainter p; p.begin(&pic);

    // 绘制图形的代码

    // 判断当前绘制的是选中的图形 if (_drawType == SELECT && _selectedRect.isValid()) { // 设置选中图形的属性 p.setPen(QPen(Qt::red, 2)); // 设置红色边框和2像素的线宽 p.setBrush(Qt::green); // 设置绿色填充颜色 }

    // 绘制图形的代码

    p.end(); // 显示图形 } ```

  4. 修改mousePressEvent函数,在鼠标按下时判断鼠标点下的位置是否在已绘制的图形内部,如果是,则将当前选中的图形设为该图形。 ```c++ void MainWindow::mousePressEvent(QMouseEvent* event) { // 判断当前绘制的是选中状态 if (_drawType == SELECT) { // 遍历图形容器,判断鼠标点击位置在哪个图形内部 for (const QRect& rect : _rects) { if (rect.contains(event->pos())) { cont._selectedRect = rect; break; } }

       // 遍历图形容器,判断鼠标点击位置在哪个图形内部
       for (const QRect& rect : _ellipse)
       {
           if (rect.contains(event->pos())) 
           {
               cont._selectedRect = rect;
               break;
           }
       }
    
       // 遍历图形容器,判断鼠标点击位置在哪个图形内部
       for (const QRect& rect : _line)
       {
           if (rect.contains(event->pos())) 
           {
               cont._selectedRect = rect;
               break;
           }
       }
    
       // 重新绘制窗口,更新选中图形的样式
       update();
    

    }

    // 其他操作逻辑的代码 } ```

  5. 修改mouseMoveEvent函数,在鼠标移动时判断当前是否在拖拽选中的图形。 ```c++ void MainWindow::mouseMoveEvent(QMouseEvent* event) { // 判断是否在拖拽选中的图形 if (_drawType == SELECT && cont._selectedRect.isValid()) { // 移动选中的图形 QPoint delta = event->pos() - cont._begin; cont._selectedRect.translate(delta);

       // 更新起始位置为当前位置
       cont._begin = event->pos();
    
       // 重新绘制窗口,更新选中图形的位置
       update();
    

    }

    // 其他操作逻辑的代码 } ```

通过以上步骤,你将能够实现选中已画出的图形并对其进行操作,包括修改属性和移动图形。请注意,以上是伪代码示例,你需要根据具体的需求和代码进行相应的修改和完善。



【相关推荐】



如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^

用以上思路修改后,仍无法移动,有大佬告诉我到底是哪部分错误吗
(能出结果直接采纳)

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)
    {
        if (c == cont._selectedShapeIndex && cont._movingShape)
        {
            continue;
        }

        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(Qt::NoBrush);
        }

        p.setPen(pen);

        if (cont._shape.at(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.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++;
        }
    }

    if (cont._selectedShapeIndex != -1 && cont._movingShape)
    {
        QPen selectedPen(Qt::red,cont._widths.last() , Qt::DashLine);
        p.setPen(selectedPen);
        p.setBrush(Qt::NoBrush);
        if (cont._shape.at(cont._selectedShapeIndex) == 2)
        {
            p.drawRect(cont._rects.at(cont._selectedShapeIndex));
        }
        else if (cont._shape.at(cont._selectedShapeIndex) == 3)
        {
            p.drawEllipse(cont._ellipse.at(cont._selectedShapeIndex));
        }
        else if (cont._shape.at(cont._selectedShapeIndex) == 4)
        {
            p.drawLine(
                cont._line.at(cont._selectedShapeIndex).topLeft(),
                cont._line.at(cont._selectedShapeIndex).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)  // 选择模式
        {
            if (cont._selectedShapeIndex == -1)
            {
                selectShape(e->pos());  // 尝试选中图形
            }
            else
            {
                cont._movingShape = true;  // 标记为正在移动图形
                cont._startMovePos = 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._movingShape && cont._selectedShapeIndex != -1)
                    {
                        if (cont._shape[cont._selectedShapeIndex] == 2)  // 矩形
                        {
                            cont._rects[cont._selectedShapeIndex].moveTopLeft(e->pos() - cont._startMovePos);
                            cont._startMovePos = e->pos();  // 更新移动起始位置
                        }
                        else if (cont._shape[cont._selectedShapeIndex] == 3)  // 椭圆
                        {
                            cont._ellipse[cont._selectedShapeIndex].moveTopLeft(e->pos() - cont._startMovePos);
                            cont._startMovePos = e->pos();
                        }
                        else if (cont._shape[cont._selectedShapeIndex] == 4)  // 直线
                        {
                            QPoint delta = e->pos() - cont._startMovePos;
                            cont._line[cont._selectedShapeIndex].translate(delta);
                            cont._startMovePos = 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;
        }

        else if (cont._drawType == 5)  // 选择模式
        {
            cont._lpress = false;  // 标记左键释放

            if (cont._movingShape)
            {
                cont._movingShape = false;  // 图形移动结束
            }

            // ... 其他操作
        }
    }
}

援引讯飞星火:
要实现选中已画出的图形并对其进行操作,可以在鼠标按下、移动和松开时更新选中图形的信息,并在鼠标移动时绘制选中的图形。以下是实现这个功能的代码:

  1. 在container.h中添加成员变量:
QRect selectedRect; // 选中的矩形
QRect selectedEllipse; // 选中的椭圆
QPoint selectedBegin; // 选中的直线起点
  1. 在container.cpp中添加选中图形的相关函数:
void container::selectRect(const QRect &rect) {
    if (selectedRect != rect) {
        selectedRect = rect;
        // 更新画笔颜色、填充颜色等属性
    }
}

void container::selectEllipse(const QRect &ellipse) {
    if (selectedEllipse != ellipse) {
        selectedEllipse = ellipse;
        // 更新画笔颜色、填充颜色等属性
    }
}

void container::selectLine(const QPoint &begin) {
    if (selectedBegin != begin) {
        selectedBegin = begin;
        // 更新画笔颜色、填充颜色等属性
    }
}
  1. 在MainWindow.cpp中重载鼠标按下、移动和松开函数:
void MainWindow::mousePressEvent(QMouseEvent *event) {
    if (cont._drawType == 0) { // 直线
        cont.selectLine(event->pos());
    } else if (cont._drawType == 1) { // 矩形
        cont.selectRect(cont._rects.at(cont._rects.size() - 1));
    } else if (cont._drawType == 2) { // 椭圆
        cont.selectEllipse(cont._ellipse.at(cont._ellipse.size() - 1));
    }
    cont._drag = true;
    cont._begin = event->pos();
    cont.update();
}

void MainWindow::mouseMoveEvent(QMouseEvent *event) {
    if (cont._drag) {
        cont._end = event->pos();
        cont.update();
    }
}

void MainWindow::mouseReleaseEvent(QMouseEvent *event) {
    if (cont._drag) {
        cont._drag = false;
        cont._begin = event->pos();
        cont.update();
    }
}
  1. 在MainWindow.h中添加槽函数声明:
private slots:
    void update(); // 更新画布
  1. 在MainWindow.cpp中实现update()函数:
void MainWindow::update() {
    QPainter painter(this);
    painter.setPen(cont._color);
    if (cont._isfill) {
        painter.setBrush(cont._fillcolor);
    } else {
        painter.setBrush(cont._color);
    }
    if (cont._drawType == 0) { // 直线
        painter.drawLine(cont._begin, cont._end);
    } else if (cont._drawType == 1) { // 矩形
        painter.drawRect(cont._begin.x(), cont._begin.y(), cont._end.x() - cont._begin.x(), cont._end.y() - cont._begin.y());
    } else if (cont._drawType == 2) { // 椭圆
        painter.drawEllipse(cont._begin.x(), cont._begin.y(), cont._end.x() - cont._begin.x(), cont._end.y() - cont._begin.y());
    }
}

这样,你就可以在QT实现画图功能中选中已画出的图形并对其进行操作了。


// container.h
class container {
    // ... 其他成员变量 ...
    int _selectedShapeIndex;  // 记录选中图形的索引
public:
    // ... 其他成员函数 ...
    void setSelectedShapeIndex(int index) { _selectedShapeIndex = index; }
    int getSelectedShapeIndex() { return _selectedShapeIndex; }
};

// MainWindow.cpp
void MainWindow::mousePressEvent(QMouseEvent* e) {
    if (e->button() == Qt::LeftButton) {
        // 检查鼠标是否在图形内部
        for (int c = 0; c < cont._shape.size(); ++c) {
            if (cont._shape.at(c) == 2) {  // 矩形
                if (cont._rects.at(c).contains(e->pos())) {
                    cont.setSelectedShapeIndex(c);  // 设置选中图形的索引
                    break;
                }
            } else if (cont._shape.at(c) == 3) {  // 椭圆
                // ... 类似检查椭圆的方式 ...
            }
            // ... 其他图形类型 ...
        }
    }
}

void MainWindow::mouseMoveEvent(QMouseEvent* e) {
    if (cont.getSelectedShapeIndex() != -1) {  // 已选中图形
        int selectedShapeIndex = cont.getSelectedShapeIndex();
        if (cont._shape.at(selectedShapeIndex) == 2) {  // 矩形
            if (cont._rects.at(selectedShapeIndex).contains(e->pos())) {
                setCursor(Qt::SizeAllCursor);
                cont._drag = 1;
            } else {
                setCursor(Qt::ArrowCursor);
                cont._drag = 0;
            }
        }
        // ... 类似地处理其他图形类型 ...
    }
}

void MainWindow::mouseReleaseEvent(QMouseEvent* e) {
    // ...
    cont.setSelectedShapeIndex(-1);  // 重置选中图形索引
    // ...
}

void MainWindow::modifyLineWidth(int width) {
    int selectedShapeIndex = cont.getSelectedShapeIndex();
    if (selectedShapeIndex != -1) {
        cont._widths[selectedShapeIndex] = width;
        update();  // 刷新绘图区域
    }
}

// ... 类似地实现其他修改属性的方法 ...

void MainWindow::moveSelectedShape(QPoint newPos) {
    int selectedShapeIndex = cont.getSelectedShapeIndex();
    if (selectedShapeIndex != -1) {
        if (cont._shape.at(selectedShapeIndex) == 2) {  // 矩形
            int dx = newPos.x() - cont._begin.x();
            int dy = newPos.y() - cont._begin.y();
            cont._rects[selectedShapeIndex].translate(dx, dy);
            cont._begin = newPos;
            update();  // 刷新绘图区域
        }
        // ... 类似地处理其他图形类型 ...
    }
}

// MainWindow.h
private slots:
    void modifyLineWidth(int width);
    // ... 其他修改属性的方法 ...
    void moveSelectedShape(QPoint newPos);

使用QT QGraphicsView图形框架实现画图功能
可以参考下


qt 绘图工具(一)_qt 画图工具_下次一定加班的博客-CSDN博客 手把手教学如何使用qt实现简单的绘图工具_qt 画图工具 https://blog.csdn.net/lllztl/article/details/127126034

要手动监听一下鼠标的位置。

引用gpt作答
下面是一个简单的示例代码,演示了如何在Qt中实现选中已画出的图形并进行操作(修改属性和移动)的功能。请注意,这仅为示例代码,您还需要根据需求进行适当的调整和扩展。

#include <QtWidgets>

class GraphicsItem : public QGraphicsRectItem
{
public:
    GraphicsItem(qreal x, qreal y, qreal width, qreal height)
        : QGraphicsRectItem(x, y, width, height)
    {
        // 设置默认属性
        setFlag(QGraphicsItem::ItemIsSelectable, true);
    }
    
    void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = nullptr) override
    {
        // 绘制图形(此处以矩形为例)
        painter->setPen(pen);
        painter->setBrush(brush);
        painter->drawRect(rect());
    }
    
    // 根据需要添加其他属性和功能
    
private:
    QPen pen;   // 边框样式
    QBrush brush;   // 填充样式
};

class GraphicsScene : public QGraphicsScene
{
public:
    void mousePressEvent(QGraphicsSceneMouseEvent* event) override
    {
        // 获取鼠标点击的位置
        QPointF pos = event->scenePos();
        
        // 判断是否点击在图形上
        QGraphicsItem* item = itemAt(pos, QTransform());
        if (item && item->isSelected()) {
            // 图形已经选中,处理选中图形的操作
            // 修改属性或移动图形
            // ...
        } else {
            // 新建一个图形并添加到场景中
            GraphicsItem* newItem = new GraphicsItem(pos.x(), pos.y(), 100, 100);
            addItem(newItem);
        }
        
        QGraphicsScene::mousePressEvent(event);
    }
};

int main(int argc, char** argv)
{
    QApplication app(argc, argv);
    
    QGraphicsView view;
    GraphicsScene scene;
    view.setScene(&scene);
    view.show();
    
    return app.exec();
}

上述示例代码中,我们创建了一个自定义的GraphicsItem类来表示绘图元素,并添加了一些默认属性和绘制逻辑。在GraphicsScene类中,我们重载了鼠标点击事件,根据鼠标点击的位置来判断是否选中了某个图形,然后进行相应的操作。

结合GPT给出回答如下请题主参考
实现选中已画出的图形并对其进行操作的一种方式是将画出的图形存储在一个容器中,每个图形都有一个唯一的标识符(例如矩形可用左上角的坐标和宽高表示),然后在鼠标点击绘图区域时,从容器中依次遍历每个图形,判断当前鼠标点击位置是否在图形内部,如果在则标记当前图形为选中状态。

对于选中的图形,可以在其周围绘制一个虚线框作为选中框,然后在属性编辑器中显示该图形的各种属性,例如边框颜色、填充颜色、线宽等。

对于修改属性,可以在属性编辑器中提供相应的控件,例如颜色选择器和滑动条,当用户修改属性时,将相应的属性值更新到选中的图形中即可。对于移动图形,可以通过鼠标拖拽选中的图形来实现。

下面是一个简化的示例代码,演示如何选中并编辑矩形:

// 定义一个矩形类,包含位置、大小和属性等信息
class Rectangle {
public:
    Rectangle(QRectF rect, QColor fill, QColor stroke, qreal strokeWidth)
        : m_rect(rect), m_fill(fill), m_stroke(stroke), m_strokeWidth(strokeWidth), m_selected(false) {}

    QRectF rect() const { return m_rect; }
    QColor fill() const { return m_fill; }
    QColor stroke() const { return m_stroke; }
    qreal strokeWidth() const { return m_strokeWidth; }
    bool isSelected() const { return m_selected; }

    void setRect(QRectF rect) { m_rect = rect; }
    void setFill(QColor fill) { m_fill = fill; }
    void setStroke(QColor stroke) { m_stroke = stroke; }
    void setStrokeWidth(qreal strokeWidth) { m_strokeWidth = strokeWidth; }
    void setSelected(bool selected) { m_selected = selected; }

private:
    QRectF m_rect;
    QColor m_fill;
    QColor m_stroke;
    qreal m_strokeWidth;
    bool m_selected;
};

// 定义一个画布类,管理矩形列表和绘制逻辑
class Canvas : public QWidget {
public:
    Canvas(QWidget *parent = nullptr) : QWidget(parent) {}

    void addRectangle(QRectF rect, QColor fill, QColor stroke, qreal strokeWidth) {
        m_rectangles.append(Rectangle(rect, fill, stroke, strokeWidth));
        update();
    }

protected:
    void paintEvent(QPaintEvent *event) {
        QPainter painter(this);
        painter.setRenderHint(QPainter::Antialiasing);

        // 绘制所有矩形
        for (const Rectangle &rect : m_rectangles) {
            painter.setBrush(QBrush(rect.fill()));
            painter.setPen(QPen(rect.stroke(), rect.strokeWidth()));
            painter.drawRect(rect.rect());

            // 如果矩形被选中,则在其周围绘制选中框
            if (rect.isSelected()) {
                painter.setPen(QPen(Qt::DashLine));
                painter.drawRect(rect.rect().adjusted(-5, -5, 5, 5));
            }
        }
    }

    void mousePressEvent(QMouseEvent *event) {
        // 遍历所有矩形,判断是否有矩形被点击
        for (int i = m_rectangles.size() - 1; i >= 0; i--) {
            Rectangle &rect = m_rectangles[i];
            if (rect.rect().contains(event->pos())) {
                // 找到被点击的矩形,则将其设置为选中状态,并更新属性编辑器
                rect.setSelected(true);
                emit rectangleSelected(&rect);
                break;
            }
        }

        update();
    }

    void mouseMoveEvent(QMouseEvent *event) {
        // 如果有选中的矩形,则将其位置移动到鼠标位置
        for (Rectangle &rect : m_rectangles) {
            if (rect.isSelected()) {
                rect.setRect(QRectF(event->pos(), rect.rect().size()));
                update();
                break;
            }
        }
    }

    void mouseReleaseEvent(QMouseEvent *event) {
        // 取消所有选中的矩形
        for (Rectangle &rect : m_rectangles) {
            rect.setSelected(false);
        }

        emit rectangleSelected(nullptr);

        update();
    }

signals:
    void rectangleSelected(Rectangle *rect);

private:
    QList<Rectangle> m_rectangles;
};

// 定义一个属性编辑器类,提供编辑选中矩形的各种属性
class PropertyEditor : public QWidget {
    Q_OBJECT

public:
    PropertyEditor(QWidget *parent = nullptr) : QWidget(parent) {
        m_fillColorPicker = new QColorDialog(this);
        m_strokeColorPicker = new QColorDialog(this);
        m_strokeWidthSlider = new QSlider(Qt::Horizontal, this);
        m_strokeWidthSlider->setRange(1, 10);

        m_layout = new QVBoxLayout();
        m_layout->addWidget(new QLabel("Fill color:"));
        m_layout->addWidget(m_fillColorPicker);
        m_layout->addWidget(new QLabel("Stroke color:"));
        m_layout->addWidget(m_strokeColorPicker);
        m_layout->addWidget(new QLabel("Stroke width:"));
        m_layout->addWidget(m_strokeWidthSlider);

        setLayout(m_layout);

        connect(m_fillColorPicker, &QColorDialog::currentColorChanged, this, &PropertyEditor::onFillColorChanged);
        connect(m_strokeColorPicker, &QColorDialog::currentColorChanged, this, &PropertyEditor::onStrokeColorChanged);
        connect(m_strokeWidthSlider, &QSlider::valueChanged, this, &PropertyEditor::onStrokeWidthChanged);
    }

public slots:
    void setRectangle(Rectangle *rect) {
        m_rectangle = rect;
        if (m_rectangle) {
            m_fillColorPicker->setCurrentColor(rect->fill());
            m_strokeColorPicker->setCurrentColor(rect->stroke());
            m_strokeWidthSlider->setValue(rect->strokeWidth());
        } else {
            m_fillColorPicker->setCurrentColor(Qt::white);
            m_strokeColorPicker->setCurrentColor(Qt::black);
            m_strokeWidthSlider->setValue(1);
        }
    }

signals:
    void fillColorChanged(QColor color);
    void strokeColorChanged(QColor color);
    void strokeWidthChanged(qreal width);

private slots:
    void onFillColorChanged(QColor color) {
        if (m_rectangle) {
            m_rectangle->setFill(color);
            emit fillColorChanged(color);
        }
    }

    void onStrokeColorChanged(QColor color) {
        if (m_rectangle) {
            m_rectangle->setStroke(color);
            emit strokeColorChanged(color);
        }
    }

    void onStrokeWidthChanged(int width) {
        if (m_rectangle) {
            m_rectangle->setStrokeWidth(width);
            emit strokeWidthChanged(width);
        }
    }

private:
    Rectangle *m_rectangle = nullptr;
    QVBoxLayout *m_layout;
    QColorDialog *m_fillColorPicker;
    QColorDialog *m_strokeColorPicker;
    QSlider *m_strokeWidthSlider;
};

// 在主窗口中创建画布和属性编辑器,并连接选中矩形的信号和属性编辑器的更新槽
class MainWindow : public QMainWindow {
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr) : QMainWindow(parent) {
        m_canvas = new Canvas(this);
        m_propertyEditor = new PropertyEditor(this);

        setCentralWidget(m_canvas);
        addDockWidget(Qt::RightDockWidgetArea, m_propertyEditor);

        connect(m_canvas, &Canvas::rectangleSelected, m_propertyEditor, &PropertyEditor::setRectangle);
        connect(m_propertyEditor, &PropertyEditor::fillColorChanged, this, &MainWindow::updateCanvas);
        connect(m_propertyEditor, &PropertyEditor::strokeColorChanged, this, &MainWindow::updateCanvas);
        connect(m_propertyEditor, &PropertyEditor::strokeWidthChanged, this, &MainWindow::updateCanvas);
    }

public slots:
    void updateCanvas() {
        m_canvas->update();
    }

private:
    Canvas *m_canvas;
    PropertyEditor *m_propertyEditor;
};