• 《QT从基础到进阶·十五》用鼠标绘制矩形(QGraphicsView、QPainter、QGraphicsRectItem)


    以下是鼠标绘制矩形最全的一种用法,完整源码将会放在最后面。
    QT版本:5.15.2
    VS版本:2019

    1、在界面加载一张图片
    界面的搭建选用QGraphicsView,自定义类GraphicsView继承QGraphicsView,在主程序中点击按钮打开 图片,相关代码如下:

    void testString::on_button_clicked()
    {
    
        QString fileName = QFileDialog::getOpenFileName(this, "open", QStandardPaths::writableLocation(QStandardPaths::PicturesLocation), "image (*.bmp *.png *.jpg)");
        if (fileName.isEmpty())
        {
            return;
        }
        QImage image(fileName);
        gview->setBackImage(image);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在这里插入图片描述

    2、创建矩形绘制对象,并绘制、移动矩形
    在GraphicsView类中创建矩形绘制对象,并初始化该对象用于绘制矩形。在GraphicsView类的鼠标事件中设置绘制矩形时鼠标按下,移动,释放操作。

    DrawROI* m_drawROI;
    m_drawROI = new DrawROI(this);
    m_drawROI->isDrawMultipleROIs(false);  //是否允许画多个矩形
    
    void GraphicsView::mousePressEvent(QMouseEvent* event)
    {
    	QPoint nViewPoint = event->pos();
    	m_drawROI->changeROIBegin(nViewPoint);
    	QGraphicsView::mousePressEvent(event);
    }
    
    void GraphicsView::mouseMoveEvent(QMouseEvent* event)
    {
        //鼠标按住左键移动
        if (event->buttons() & Qt::LeftButton) {
            //绘制矩形时鼠标移动处理
            m_drawROI->changeROIInProgress(event->pos());
        }
        //设置鼠标形状
        m_drawROI->changeMouseShape(event->pos());
        
        QGraphicsView::mouseMoveEvent(event);
    }
    
    void GraphicsView::mouseReleaseEvent(QMouseEvent* event)
    {
        if (event->button() == Qt::LeftButton) {
            //矩形绘制结束
            m_drawROI->changeROIEnd(event->pos());
        }
    
        QGraphicsView::mouseReleaseEvent(event);
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    在这里插入图片描述

    3、对绘制的矩形长宽进行修改和界面缩放
    矩形长宽的拖动会在DrawROI类中实现,界面的缩放把DrawROI类中的功能放入GraphicsView中的滚轮事件中

    void GraphicsView::wheelEvent(QWheelEvent* ev)
    {
        //放大图元
        m_graphicsViewTool->ScaleImage(ev);
        //图元放大,在图元上画的矩形不会放大,下面方法是让画的矩形和图元同比例放大,这里的画框是用QPainter方式,画出的东西不会随QGraphicsItem图元改变而改变
        //如果在图元上依然用QGraphicsItem图元来画框,那他们会一起改变,自动同比例放大缩小,因为都是属于QGraphics系列
        m_drawROI->ScaleROIS(ev, m_graphicsViewTool->GetScale());
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述

    4、绘制多个矩形并进行删除保存
    绘制多个矩形需要做如下设置:

    m_drawROI->isDrawMultipleROIs(true);  //是否允许画多个矩形
    
    • 1

    对矩形进行右键删除和保存需要用到GraphicsView的右键菜单事件

     m_pOptMenu = new QMenu(this);
     m_pDelAction = new QAction(QStringLiteral("删除"), this);
     connect(m_pDelAction, &QAction::triggered, m_drawROI, &DrawROI::DeleteCurrentROI);
     m_pSaveAction = new QAction(QStringLiteral("保存"), this);
     connect(m_pSaveAction, &QAction::triggered, m_drawROI, &DrawROI::saveAllROIImage);
    
        m_pOptMenu->addAction(m_pDelAction);
        m_pOptMenu->addAction(m_pSaveAction);
    
    void GraphicsView::contextMenuEvent(QContextMenuEvent* ev)
    {
        QPoint mousePos = ev->pos();
    
        //QRect.contains被给的点在矩形内部返回true
        //场景坐标
        QPointF fScenePoint = this->mapToScene(mousePos);
        //图形项坐标
        QGraphicsItem* pItem = this->scene()->itemAt(fScenePoint, QTransform());
    
        if (NULL != pItem)
        {
            QPointF fItemPoint = pItem->mapFromScene(fScenePoint);   //获取图形项坐标
            QPoint itemPoint(fItemPoint.x(), fItemPoint.y());
    
            for (int i = 0; i < m_drawROI->getRoiRect().size(); i++)
            {
                if (m_drawROI->getRoiRect()[i].contains(itemPoint))
                {
                    m_pOptMenu->exec(QCursor::pos());
                    break;
                }
            }
        }
        ev->accept();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    在这里插入图片描述

    =====================
    完整源码下载

    在这里插入图片描述

    📢博客主页: 主页
    📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!
    📢本文由 梦回阑珊 原创,首发于 CSDN,转载注明出处🙉
    📢代码改变世界,你来改变代码!✨

  • 相关阅读:
    剑指 Offer 38. 字符串的排列
    dreamweaver网页设计作业制作 学生个人网页猫眼电影 WEB静态网页作业模板 大学生个人主页博客网页代码 dw个人网页作业成品
    PC辉光效果一切正常,安卓辉光却没效果、显示异常(爆闪、黑屏等)
    Java JVM中的栈空间怎么释放
    【LeetCode-中等题】904. 水果成篮
    3.6 shellcode编码技术
    vscode+phpstudy断点调试php程序
    centos安装NIS
    go语言相关bug
    Spring事务2+银行转账拓展
  • 原文地址:https://blog.csdn.net/cs1395293598/article/details/134303558