• 《QT从基础到进阶·二十六》绘制多个图形项(QGraphicsRectItem,QGraphicsLineItem,QGraphicsPolygonItem)


    这个demo用QT实现了对多个图形项的绘制,包括矩形的绘制,直线的绘制和多边形的绘制,是之前一章中绘制矩形的增强版,之前一章节关于矩形的绘制可以参考:《QT从基础到进阶·十五》用鼠标绘制矩形(QGraphicsView、QPainter、QGraphicsRectItem)

    对比于之前一章关于矩形的绘制,在这一章节中对多个图形项的绘制用了一种新的实现方式:
    1、创建了DrawControl类管理所有绘制的图形项,同时DrawControl被外部调用;
    2、创建drawRect继承QGraphicsRectItem,用于绘制矩形;
    3、创建drawLine继承QGraphicsLineItem,用于绘制直线;
    4、创建drawPolygon继承QGraphicsPolygonItem,用于绘制多边形
    后续可以继续追加其他图形项的绘制,所有图形项都被DrawControl管理。

    源码放在最后面

    DrawControl目前包含一个头文件(DrawPolygons.h)和一个CPP文件(DrawPolygons.cpp),头文件对外暴露的接口如下:

    class DrawControl : public QObject
    {
    	Q_OBJECT
    public:
    	DrawControl(QGraphicsView* view, QGraphicsScene* sence, QObject* parent = nullptr);
    	~DrawControl();
    
    public:
    	//创建绘画类型:矩形,圆...
    	//isPaintingEnable设置false表示通过参数绘制多边形,同时禁用paint绘画功能
    	QGraphicsItem* createDrawObject(polygons drawType, color color,int penWidth = 1, bool isPaintingEnable = false);
    
    	//根据矩形参数绘制矩形
    	void draw_Rect(QRect rect, QGraphicsItem* itemPtr);
    
    	//根据直线参数绘制直线
    	void draw_Line(QLine line, QGraphicsItem* itemPtr);
    
    	//根据多边形参数绘制多边形
    	void draw_Polygon(QPolygon polygon, QGraphicsItem* itemPtr);
    	
    public:
    	//获取所有创建的图形项item对象指针
    	std::map<polygons, std::map<int, QGraphicsItem*>> getAllGraphicsItems();
    
    	//鼠标按下开始绘画,需接收QGraphicsView中的mousePressEvent事件坐标(视图view坐标)
    	void mouseDrawBegin(polygons drawType, const QPoint& point, QGraphicsItem* itemPtr, Qt::MouseButton button = Qt::MouseButton::LeftButton);
    
    	//鼠标已经按下,移动鼠标进行绘画或者移动多边形,需接收QGraphicsView中的mouseMoveEvent事件坐标(视图view坐标)
    	void mouseDrawProgress(polygons drawType, const QPoint& point, QGraphicsItem* itemPtr);
    
    	//鼠标松开,完成绘画或完成拖动,需接收QGraphicsView中的mouseReleaseEvent事件坐标(视图view坐标)
    	void mouseDrawEnd(polygons drawType, const QPoint& point, QGraphicsItem* itemPtr, Qt::MouseButton button = Qt::MouseButton::LeftButton);
    
    	//实时更新鼠标形状,需接收QGraphicsView中的mouseMoveEvent事件坐标(视图view坐标)
    	void updateMouseShape(polygons drawType, const QPoint& point, QGraphicsItem* itemPtr);
    }
    
    • 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
    • 36
    • 37

    目前绘制图形项有两种方式:
    (1)通过对DrawControl传参自动绘制图形项
    (2)通过DrawControl的鼠标事件手动用鼠标绘制图形项

    下面分别说下两种方式的使用:
    (1)通过对DrawControl传参自动绘制图形项
    第一步:我们需要在自定义GraphicsView类中包含DrawPolygons.h头文件,并声明DrawControl指针,同时在声明要绘制的图形项的指针。

     DrawControl* drawControl;  //声明所有图形项管理器指针
     QGraphicsItem* rect_item;  //声明矩形指针
     QGraphicsItem* line_item;  //声明直线指针
     QGraphicsItem* polygons_item;  //声明多边形指针
    
    • 1
    • 2
    • 3
    • 4

    第二步:在自定义GraphicsView类中创建DrawControl对象,并通过DrawControl管理器分别创建要绘制的图形项对象。

    //创建DrawControl对象需要传入QGraphicsView和QGraphicsScene指针
    drawControl = new DrawControl(this, m_scene);
    rect_item = drawControl->createDrawObject(polygons::rect, color::blue);  //创建矩形对象
    polygons_item = drawControl->createDrawObject(polygons::polygon, color::red); //创建多边形对象
    line_item = drawControl->createDrawObject(polygons::line, color::red);  //创建直线对象
    
    • 1
    • 2
    • 3
    • 4
    • 5

    createDrawObject接口分析:

    QGraphicsItem* createDrawObject(polygons drawType, color color,int penWidth = 1, bool isPaintingEnable = false);
    
    • 1

    参数1:要创建哪个图形项对象,为enum类型;

    typedef enum Polygons
    {
    	rect,  //矩形
    	line,  //直线
    	polygon, //多边形
    	none
    }polygons;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    参数2:绘制的线条颜色,enum类型;

    typedef enum Color
    {
    	red,
    	blue,
    	black
    }color;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    参数3:绘制图形项时线条的宽度,默认为1;
    参数4:是否禁用paint绘制事件,默认为false,表示方式1,通过给参数自动创建图形项,设置true表示方式2,可以用鼠标手动绘制图形项。

    第三步:设置参数自动绘制矩形,直线和多边形

    void GraphicsView::drawPolygon_()
    {
        //绘制矩形
        drawControl->draw_Rect(QRect(0, 0, 100, 100), rect_item);
        
        //绘制多边形
        QPolygon polygon;
        polygon << QPoint(200, 100) << QPoint(250, 150) << QPoint(150, 150) << QPoint(150, 100);
        drawControl->draw_Polygon(polygon, polygons_item);
    
        //绘制直线
        drawControl->draw_Line(QLine(80,80,180,80), line_item);
        
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    矩形左上角坐标为(0, 0)点,宽高为100。多边形分别设置点(200, 100),(250, 150),(150, 150), (150, 100),坐标相连实际绘制一个梯形。直线两点坐标分别为(80, 80), (180, 80),是一条水平线。示意图如下:
    在这里插入图片描述

    (2)通过DrawControl的鼠标事件手动用鼠标绘制图形项

    1、用鼠标手动绘制矩形

    在GraphicsView构造中创建DrawControl绘制管理器对象和矩形对象。

    //创建绘制管理器对象
     drawControl = new DrawControl(this, m_scene);
     //创建矩形对象,绘制线条设置蓝色,线条宽度设置1, true开启paint绘制事件
     rect_item = drawControl->createDrawObject(polygons::rect, color::blue, 1, true);
    
    • 1
    • 2
    • 3
    • 4

    在GraphicsView鼠标事件中调用drawControl 中的鼠标事件,主要有三个鼠标事件:鼠标按下,鼠标移动,鼠标放开。
    drawControl的鼠标事件接口分析:

    //鼠标按下开始绘画,需接收QGraphicsView中的mousePressEvent事件坐标(视图view坐标)
    void mouseDrawBegin(polygons drawType, const QPoint& point, QGraphicsItem* itemPtr, Qt::MouseButton button = Qt::MouseButton::LeftButton);
    
    • 1
    • 2

    参数1:上文说到的绘制类,enum类型;
    参数2:传入的鼠标点击的坐标;
    参数3:绘制的图形项指针;
    参数4:传入鼠标左键按下还是右键按下,默认左键按下

    //鼠标已经按下,移动鼠标进行绘画或者移动多边形,需接收QGraphicsView中的mouseMoveEvent事件坐标(视图view坐标)
    void mouseDrawProgress(polygons drawType, const QPoint& point, QGraphicsItem* itemPtr);
    
    • 1
    • 2

    参数1:上文说到的绘制类,enum类型;
    参数2:传入鼠标移动时的坐标;
    参数3:绘制的图形项指针;

    //鼠标松开,完成绘画或完成拖动,需接收QGraphicsView中的mouseReleaseEvent事件坐标(视图view坐标)
    void mouseDrawEnd(polygons drawType, const QPoint& point, QGraphicsItem* itemPtr, Qt::MouseButton button = Qt::MouseButton::LeftButton);
    
    • 1
    • 2

    参数1:上文说到的绘制类,enum类型;
    参数2:传入鼠标松开的坐标;
    参数3:绘制的图形项指针;
    参数4:传入鼠标左键松开还是右键松开,默认左键松开

    GraphicsView中的调用:

    //鼠标按下
    void GraphicsView::mousePressEvent(QMouseEvent* event)
    {
    	drawControl->mouseDrawBegin(polygons::rect, event->pos(), rect_item);
    	QGraphicsView::mousePressEvent(event);
    }
    
    //鼠标移动
    void GraphicsView::mouseMoveEvent(QMouseEvent* event)
    {
       drawControl->mouseDrawProgress(polygons::rect, event->pos(), rect_item);
       //updateMouseShape能够更新鼠标移动时鼠标箭头图标变化,比如鼠标移入矩形内会从箭头变为手,目前只实现了矩形鼠标图标变化
       drawControl->updateMouseShape(polygons::rect, event->pos(), rect_item);
       QGraphicsView::mouseMoveEvent(event);
    }
    
    //鼠标放开
    void GraphicsView::mouseReleaseEvent(QMouseEvent* event)
    {
        drawControl->mouseDrawEnd(polygons::rect, event->pos(), rect_item);
        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

    效果示意图如下:
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/61b69688381a4e579df37ec46946f43d.gif

    2、用鼠标绘制直线

    //GraphicsView.cpp
     drawControl = new DrawControl(this, m_scene);
     line_item = drawControl->createDrawObject(polygons::line, color::red, 1, true);
    
    • 1
    • 2
    • 3

    GraphicsView中的调用:

    //鼠标按下
    void GraphicsView::mousePressEvent(QMouseEvent* event)
    {
    	drawControl->mouseDrawBegin(polygons::line, event->pos(), line_item);
    	QGraphicsView::mousePressEvent(event);
    }
    
    //鼠标移动
    void GraphicsView::mouseMoveEvent(QMouseEvent* event)
    {
       drawControl->mouseDrawProgress(polygons::line, event->pos(), line_item);
       QGraphicsView::mouseMoveEvent(event);
    }
    
    //鼠标放开
    void GraphicsView::mouseReleaseEvent(QMouseEvent* event)
    {
        drawControl->mouseDrawEnd(polygons::line, event->pos(), line_item);
        QGraphicsView::mouseReleaseEvent(event);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    效果示意图如下:
    在这里插入图片描述

    3、用鼠标绘制多边形

    //GraphicsView.cpp
     drawControl = new DrawControl(this, m_scene);
     polygons_item = drawControl->createDrawObject(polygons::polygon, color::red, 1, true);
    
    • 1
    • 2
    • 3

    GraphicsView中的调用:

    //鼠标按下
    void GraphicsView::mousePressEvent(QMouseEvent* event)
    {
    	//绘制多边形涉及鼠标左右键点击,所有需要最后一个参数需要传入鼠标类型
    	drawControl->mouseDrawBegin(polygons::line, event->pos(), line_item, event->button());
    	QGraphicsView::mousePressEvent(event);
    }
    
    //鼠标移动
    void GraphicsView::mouseMoveEvent(QMouseEvent* event)
    {
       drawControl->mouseDrawProgress(polygons::polygon, event->pos(), polygons_item);
       QGraphicsView::mouseMoveEvent(event);
    }
    
    //鼠标放开
    void GraphicsView::mouseReleaseEvent(QMouseEvent* event)
    {
        drawControl->mouseDrawEnd(polygons::polygon, event->pos(), polygons_item,  event->button());
        QGraphicsView::mouseReleaseEvent(event);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    注意:多边形的绘制是先点击鼠标左键不松开,再点击右键,松开右键后确定第一个点,这时鼠标左键依旧不松开,移到其他地方再点击右键,松开右键确定第二个点,以此往复,当松开鼠标左键后会自动把这些点连成线形成一个多边形。

    效果示意图如下:
    在这里插入图片描述

    源码下载

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

  • 相关阅读:
    Python项目运行过程报错处理
    Spring Cloud学习:二【详细】
    golang sync.Map 在函数传参时默认是值传递
    Python可视化数据分析-饼状图
    数据结构-顺序表
    FreeRTOS实时操作系统 —基于STM32
    ARM Cortex-M0 内核寄存器组
    C++ 左值和右值
    电脑技巧:推荐一款桌面增强工具AquaSnap
    素皮材质的手机壳,如何才能做到经久耐用?
  • 原文地址:https://blog.csdn.net/cs1395293598/article/details/134397299