当前位置: 首页 > news >正文

《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)通过对DrawControl传参自动绘制图形项
(2)通过DrawControl的鼠标事件手动用鼠标绘制图形项

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

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

第二步:在自定义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);  //创建直线对象

createDrawObject接口分析:

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

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

typedef enum Polygons
{rect,  //矩形line,  //直线polygon, //多边形none
}polygons;

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

typedef enum Color
{red,blue,black
}color;

参数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);}

矩形左上角坐标为(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);

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

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

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

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

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

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

参数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);
}

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

2、用鼠标绘制直线

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

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);
}

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

3、用鼠标绘制多边形

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

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);
}

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

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

源码下载

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

相关文章:

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

这个demo用QT实现了对多个图形项的绘制&#xff0c;包括矩形的绘制&#xff0c;直线的绘制和多边形的绘制&#xff0c;是之前一章中绘制矩形的增强版&#xff0c;之前一章节关于矩形的绘制可以参考&#xff1a;《QT从基础到进阶十五》用鼠标绘制矩形&#xff08;QGraphicsView、…...

【分布式】CAP理论详解

一、CAP理论概述 在分布式系统中&#xff0c;CAP是指一组原则&#xff0c;它们描述了在网络分区&#xff08;Partition&#xff09;时&#xff0c;分布式系统能够提供的保证。CAP代表Consistency&#xff08;一致性&#xff09;、Availability&#xff08;可用性&#xff09;和…...

AI歌姬,C位出道,基于PaddleHub/Diffsinger实现音频歌声合成操作(Python3.10)

懂乐理的音乐专业人士可以通过写乐谱并通过乐器演奏来展示他们的音乐创意和构思&#xff0c;但不识谱的素人如果也想跨界玩儿音乐&#xff0c;那么门槛儿就有点高了。但随着人工智能技术的快速迭代&#xff0c;现在任何一个人都可以成为“创作型歌手”&#xff0c;即自主创作并…...

ZooKeeper基本知识

1.什么是ZooKeeper ZooKeeper是一个开源的分布式协调服务&#xff0c;它提供了一个高性能、高可靠的分布式协调基础&#xff0c;用于构建分布式系统。 具体来说&#xff0c;ZooKeeper通常用于以下几个方面&#xff1a; 配置管理&#xff1a;分布式系统通常需要集中管理配置信…...

leetcode:138. 随机链表的复制

一、题目&#xff1a; 138. 随机链表的复制 - 力扣&#xff08;LeetCode&#xff09; 函数原型&#xff1a; struct Node* copyRandomList(struct Node* head) 二、思路 本题是给出一个单链表&#xff0c;单链表的每个结点还额外有一个随机指针&#xff0c;随机指向其他结点&am…...

SpringBoot 全局异常之参数校验(1)

文章目录 前言背景依赖校验类型@NotBlank、@NotNull和@NotEmpty的区别@Valid和@Validated区别异常处理方式一 @RequestParam全局异常处理(ConstraintViolationException)请求示例方式二 @RequestBody(推荐)全局异常处理(MethodArgumentNotValidException)请求示例方式三(…...

QT windows与linux之间sokcet通信中文乱码问题解决方法

QT windows与linux之间sokcet通信中文乱码问题解决方法 linux发送与接收都转码utf-8: tcpClient ->write( send_msg.toUtf8());//解决乱码&#xff0c;发送转码 接收&#xff1a; QByteArray buffer tcpClient->readAll(); if(!buffer.isEmpty()) { // ui->plain…...

Java实现DXF文件转换成PDF

代码实现 public static void dxfToPdf(){// 加载DXF文件String inputFile "input.dxf";CadImage cadImage (CadImage) Image.load(inputFile);// 设置PDF输出选项PdfOptions pdfOptions new PdfOptions();pdfOptions.setPageWidth(200);pdfOptions.setPageHeigh…...

揭秘Vue中的nextTick:异步更新队列背后的技术原理大揭秘!

&#x1f3ac; 江城开朗的豌豆&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 &#x1f4dd; 个人网站 :《 江城开朗的豌豆&#x1fadb; 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! 目录 ⭐ 专栏简介 &#x1f4d8; 文章引言 一、N…...

PHP使用文件缓存实现html静态化

<?php // 动态生成的内容 $content "<html><body><h1>time:".date("Y-m-d H:i:s")."</h1></body></html>"; // 静态文件保存路径和文件名 $staticFilePath "file.html"; if(file_exists($s…...

A Gentle Introduction to Graph Neural Networks

A Gentle Introduction to Graph Neural Networks----《图神经网络入门》 图神经网络信息传递积累 图在我们身边随处可见&#xff0c;现实世界中的物体通常是根据它们与其他事物的联系来定义的。一组物体以及它们之间的联系可以很自然地用图来表示。十多年来&#xff0c;研究人…...

详解[ZJCTF 2019]NiZhuanSiWei 1(PHP两种伪协议、PHP反序列化漏洞、PHP强比较)还有那道题有这么经典?

题目环境&#xff1a; <?php $text $_GET["text"]; $file $_GET["file"]; $password $_GET["password"]; if(isset($text)&&(file_get_contents($text,r)"welcome to the zjctf")){echo "<br><h1>&…...

bazel build使用【未完】

1. install install的作用&#xff1a;将生成的目标、文件复制到指定的安装目录中&#xff0c;可以是可执行文件、库文件、 配置文件等 若有一个c可执行文件&#xff0c;可以使用install将其安装到标准的可执行路径中&#xff0c;以便于直接运行&#xff0c;而无需指定完整的文…...

11-13 /11-14代理模式 AOP

调用者 代理对象 目标对象 代理对象除了可以完成核心任务&#xff0c;还可以增强其他任务,无感的增强 代理模式目的: 不改变目标对象的目标方法的前提,去增强目标方法 分为:静态代理,动态代理 静态代理 有对象->前提需要有一个类&#xff0c;那么我们可以事先写好一个类&a…...

Ubuntu 创建并发布 Django 项目

Ubuntu 创建并发布 Django 项目 升级操作系统和软件 sudo apt updatesudo apt -y dist-upgrade 安装 python3-pip sudo apt -y install python3-pip安装 django pip install -i https://pypi.tuna.tsinghua.edu.cn/simple djangosudo apt -y install python3-django创建 dj…...

SQL Server进阶知识

&#x1f648;作者简介&#xff1a;练习时长两年半的Java up主 &#x1f649;个人主页&#xff1a;程序员老茶 &#x1f64a; ps:点赞&#x1f44d;是免费的&#xff0c;却可以让写博客的作者开心好久好久&#x1f60e; &#x1f4da;系列专栏&#xff1a;Java全栈&#xff0c;…...

TFHEpp 使用记录

TFHEpp 使用记录 使用HE3DB错误randen 使用 需要使用 编译器gcc > 10 (unicode 编码) sudo apt-get install -y build-essential g-10 apt-utils ca-certificates git cmake libgmp-dev libfftw3-devgit clone https://github.com/virtualsecureplatform/TFHEpp cd TFHEp…...

大模型的实践应用6-百度文心一言的基础模型ERNIE的详细介绍,与BERT模型的比较说明

大家好,我是微学AI,今天给大家讲一下大模型的实践应用6-百度文心一言的基础模型ERNIE的详细介绍,与BERT模型的比较说明。在大规模语料库上预先训练的BERT等神经语言表示模型可以很好地从纯文本中捕获丰富的语义模式,并通过微调的方式一致地提高各种NLP任务的性能。然而,现…...

vue:如何把后端传过来的数组的其中一个对象加入新的属性

加入我们是更改数组中的第一个对象&#xff0c;在vue中可以使用$set方法将属性插入到第一个对象中作为属性。 Script部分&#xff1a; <script>export default {data() {return {boxes: [//模拟后端传过来的数组{id:1,name:张三},{id:2,name:李四},{id:3,name:王五},{i…...

数据库数据恢复—MSSQL报错“附加数据库错误823”如何恢复数据?

数据库故障&分析&#xff1a; MSSQL Server数据库比较常见的报错是“附加数据库错误823”。如果数据库有备份&#xff0c;只需要还原备份即可&#xff1b;如果无备份或者备份不可用&#xff0c;则需要使用专业的数据恢复手段去恢复数据。 MSSQL Server数据库出现“823”的报…...

使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装

以下是基于 vant-ui&#xff08;适配 Vue2 版本 &#xff09;实现截图中照片上传预览、删除功能&#xff0c;并封装成可复用组件的完整代码&#xff0c;包含样式和逻辑实现&#xff0c;可直接在 Vue2 项目中使用&#xff1a; 1. 封装的图片上传组件 ImageUploader.vue <te…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

排序算法总结(C++)

目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指&#xff1a;同样大小的样本 **&#xff08;同样大小的数据&#xff09;**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...

Kafka入门-生产者

生产者 生产者发送流程&#xff1a; 延迟时间为0ms时&#xff0c;也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于&#xff1a;异步发送不需要等待结果&#xff0c;同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...

vue3 daterange正则踩坑

<el-form-item label"空置时间" prop"vacantTime"> <el-date-picker v-model"form.vacantTime" type"daterange" start-placeholder"开始日期" end-placeholder"结束日期" clearable :editable"fal…...

es6+和css3新增的特性有哪些

一&#xff1a;ECMAScript 新特性&#xff08;ES6&#xff09; ES6 (2015) - 革命性更新 1&#xff0c;记住的方法&#xff0c;从一个方法里面用到了哪些技术 1&#xff0c;let /const块级作用域声明2&#xff0c;**默认参数**&#xff1a;函数参数可以设置默认值。3&#x…...

ZYNQ学习记录FPGA(二)Verilog语言

一、Verilog简介 1.1 HDL&#xff08;Hardware Description language&#xff09; 在解释HDL之前&#xff0c;先来了解一下数字系统设计的流程&#xff1a;逻辑设计 -> 电路实现 -> 系统验证。 逻辑设计又称前端&#xff0c;在这个过程中就需要用到HDL&#xff0c;正文…...

【Zephyr 系列 16】构建 BLE + LoRa 协同通信系统:网关转发与混合调度实战

🧠关键词:Zephyr、BLE、LoRa、混合通信、事件驱动、网关中继、低功耗调度 📌面向读者:希望将 BLE 和 LoRa 结合应用于资产追踪、环境监测、远程数据采集等场景的开发者 📊篇幅预计:5300+ 字 🧭 背景与需求 在许多 IoT 项目中,单一通信方式往往难以兼顾近场数据采集…...

基于django+vue的健身房管理系统-vue

开发语言&#xff1a;Python框架&#xff1a;djangoPython版本&#xff1a;python3.8数据库&#xff1a;mysql 5.7数据库工具&#xff1a;Navicat12开发软件&#xff1a;PyCharm 系统展示 会员信息管理 员工信息管理 会员卡类型管理 健身项目管理 会员卡管理 摘要 健身房管理…...

[C++错误经验]case语句跳过变量初始化

标题&#xff1a;[C错误经验]case语句跳过变量初始化 水墨不写bug 文章目录 一、错误信息复现二、错误分析三、解决方法 一、错误信息复现 write.cc:80:14: error: jump to case label80 | case 2:| ^ write.cc:76:20: note: crosses initialization…...