Qt/C++ 基于 QGraphicsView 的绘图软件 (附源码下载链接)
基于 Qt 的 QGraphicsView 绘图软件项目进行深入讲解,分析其核心代码与功能实现,帮助开发者理解 QGraphicsView 的用法。
项目概览
该项目实现了一个简单的绘图应用,用户可以在界面中创建和编辑矩形、椭圆、直线、多边形和文本等图形对象。功能包括添加图形、设置属性(颜色、字体)、移动、缩放、旋转、组合、删除等。
项目概览
通过网盘分享的文件:基于 QGraphicsView 的绘图软件
链接: https://pan.baidu.com/s/1g-thPifZmPKhLHJ8KFoL2w?pwd=jkcf 提取码: jkcf
核心代码讲解
1. 初始化与场景设置
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);// 创建 QGraphicsScene,并设置范围scene = new QGraphicsScene(-300, -200, 600, 400);// 将场景绑定到视图ui->View->setScene(scene);// 设置鼠标样式和拖拽模式ui->View->setCursor(Qt::CrossCursor);ui->View->setMouseTracking(true);ui->View->setDragMode(QGraphicsView::RubberBandDrag);// 初始化状态栏信息labViewCord = new QLabel(tc("View 坐标:"));labSceneCord = new QLabel(tc("Scene 坐标:"));labItemCord = new QLabel(tc("Item 坐标:"));labItemInfo = new QLabel(tc("ItemInfo: "));ui->statusBar->addWidget(labViewCord);ui->statusBar->addWidget(labSceneCord);ui->statusBar->addWidget(labItemCord);ui->statusBar->addWidget(labItemInfo);
}
- QGraphicsScene:定义绘图区域,设置范围为 (-300, -200) 到 (300, 200)。
- QGraphicsView:作为窗口的显示组件,绑定场景
scene
,支持鼠标拖拽和实时追踪。 - 状态栏:显示鼠标坐标、选中项的信息,便于交互。
2. 鼠标事件处理
鼠标移动事件
void MainWindow::on_mouseMovePoint(QPoint point)
{labViewCord->setText(tc("View 坐标:%1,%2").arg(point.x()).arg(point.y()));QPointF pointScene = ui->View->mapToScene(point);labSceneCord->setText(tc("Scene 坐标:%1,%2").arg(pointScene.x()).arg(pointScene.y()));
}
- 获取鼠标的视图坐标,并将其转换为场景坐标,通过状态栏实时显示。
鼠标单击事件
void MainWindow::on_mouseClicked(QPoint point)
{QPointF pointScene = ui->View->mapToScene(point);QGraphicsItem *item = scene->itemAt(pointScene, ui->View->transform());if (item != nullptr){QPointF pointItem = item->mapFromScene(pointScene);labItemCord->setText(tc("Item 坐标:%1,%2").arg(pointItem.x()).arg(pointItem.y()));labItemInfo->setText(item->data(ItemDesciption).toString() + tc(", ItemId=") +item->data(ItemId).toString());}
}
- 根据鼠标位置获取场景坐标,并检测该位置的绘图项。
- 如果有绘图项,显示其局部坐标和描述信息(
ItemId
和ItemDescription
)。
鼠标双击事件
void MainWindow::on_mouseDoubleClick(QPoint point)
{QPointF pointScene = ui->View->mapToScene(point);QGraphicsItem *item = scene->itemAt(pointScene, ui->View->transform());if (item == nullptr) return;switch (item->type()){case QGraphicsRectItem::Type: // 矩形{QGraphicsRectItem *theItem = qgraphicsitem_cast<QGraphicsRectItem*>(item);setBrushColor(theItem);break;}case QGraphicsEllipseItem::Type: // 椭圆{QGraphicsEllipseItem *theItem = qgraphicsitem_cast<QGraphicsEllipseItem*>(item);setBrushColor(theItem);break;}case QGraphicsTextItem::Type: // 文本{QGraphicsTextItem *theItem = qgraphicsitem_cast<QGraphicsTextItem*>(item);QFont font = QFontDialog::getFont(nullptr, theItem->font(), this, tc("设置字体"));if (font.isValid())theItem->setFont(font);break;}}
}
- 鼠标双击弹出对话框,根据绘图项类型设置填充颜色或字体。
- 使用
qgraphicsitem_cast
将QGraphicsItem
转换为具体类型。
3. 添加绘图项
添加矩形
void MainWindow::on_actItem_Rect_triggered()
{QGraphicsRectItem *item = new QGraphicsRectItem(-50, -25, 100, 50);item->setFlags(QGraphicsItem::ItemIsMovable |QGraphicsItem::ItemIsSelectable |QGraphicsItem::ItemIsFocusable);item->setBrush(QBrush(Qt::yellow));item->setZValue(++frontZ);scene->addItem(item);
}
- 使用
QGraphicsRectItem
创建矩形。 - 设置属性:
- 可移动、可选中、可聚焦。
- 填充颜色为黄色,Z 值递增(调整叠放顺序)。
添加文本
void MainWindow::on_actItem_Text_triggered()
{QString str = QInputDialog::getText(this, tc("输入文字"), tc("请输入文字"));if (str.isEmpty()) return;QGraphicsTextItem *item = new QGraphicsTextItem(str);QFont font = this->font();font.setPointSize(20);font.setBold(true);item->setFont(font);scene->addItem(item);
}
- 使用
QGraphicsTextItem
创建文本,用户通过对话框输入文字。 - 设置字体大小为 20,并加粗。
4. 操作绘图项
删除选中项
void MainWindow::on_actEdit_Delete_triggered()
{int cnt = scene->selectedItems().count();for (int i = 0; i < cnt; i++){QGraphicsItem *item = scene->selectedItems().at(0);scene->removeItem(item);}
}
- 遍历选中项列表,逐个从场景中删除。
缩放与旋转
void MainWindow::on_actZoomIn_triggered()
{ui->View->scale(1.1, 1.1); // 放大视图
}void MainWindow::on_actRotateLeft_triggered()
{ui->View->rotate(-30); // 逆时针旋转视图
}
- 放大视图的比例(
scale
)。 - 顺时针/逆时针旋转视图(
rotate
)。
组合与解除组合
void MainWindow::on_actGroup_triggered()
{QGraphicsItemGroup *group = new QGraphicsItemGroup;scene->addItem(group);foreach (QGraphicsItem *item, scene->selectedItems()){group->addToGroup(item);}
}void MainWindow::on_actGroupBreak_triggered()
{QGraphicsItemGroup *group = qgraphicsitem_cast<QGraphicsItemGroup *>(scene->selectedItems().at(0));scene->destroyItemGroup(group);
}
- 使用
QGraphicsItemGroup
将多个绘图项组合,方便整体操作。 - 使用
destroyItemGroup
解除组合。
总结
该项目通过 Qt 提供的 QGraphicsView 框架,实现了一个简单但功能丰富的绘图软件。其核心功能包括:
- 绘图功能:支持矩形、椭圆、多边形、文本等图形的添加与属性设置。
- 交互功能:支持鼠标操作、移动、缩放、旋转等。
- 编辑功能:支持组合、解除组合、删除、层次调整。
相关文章:

Qt/C++ 基于 QGraphicsView 的绘图软件 (附源码下载链接)
基于 Qt 的 QGraphicsView 绘图软件项目进行深入讲解,分析其核心代码与功能实现,帮助开发者理解 QGraphicsView 的用法。 项目概览 该项目实现了一个简单的绘图应用,用户可以在界面中创建和编辑矩形、椭圆、直线、多边形和文本等图形对象。功…...
如何使用 useMemo 和 memo 优化 React 应用性能?
使用 useMemo 和 memo 优化 React 应用性能 在构建复杂的 React 应用时,性能优化是确保应用流畅运行的关键。React 提供了多种工具来帮助开发者优化组件的渲染和计算逻辑,其中 useMemo 和 memo 是两个非常有用的 Hook。本文将详细介绍这两个工具的使用方…...

数据结构(链表 哈希表)
在Python中,链表和哈希表都是常见的数据结构,可以用来存储和处理数据。 链表是一种线性数据结构,由一系列节点组成,每个节点包含一个数据元素和一个指向下一个节点的指针。链表可以用来实现栈、队列以及其他数据结构。Python中可…...

人工智能之深度学习_[4]-神经网络入门
神经网络基础 1 神经网络 深度学习神经网络就是大脑仿生,数据从输入到输出经过一层一层的神经元产生预测值的过程就是前向传播(也叫正向传播)。 前向传播涉及到人工神经元是如何工作的(也就是神经元的初始化、激活函数…...

STM32之CubeMX图形化工具开发介绍(十七)
STM32F407 系列文章 - STM32CubeMX(十七) 目录 前言 一、CubeMX 二、下载安装 1.下载 2.安装 3.图解步骤 三、用户界面 1.项目配置 2.项目生成 3.项目文件解释 4.新建工程 5.查看原工程 四、FAQ 总结 前言 STMCube源自意法半导体…...
css3过渡总结
一、过渡的定义与作用 CSS3 过渡(Transitions)允许 CSS 属性在一定的时间区间内平滑地过渡,从一个值转变为另一个值。它能够让网页元素的状态变化更加自然、流畅,给用户带来更好的视觉体验。例如,当一个元素从隐藏状态…...

latin1_swedish_ci(latin1 不支持存储中文、日文、韩文等多字节字符)
文章目录 1、SHOW TABLE STATUS WHERE Name batch_version;2、latin1_swedish_ci使用场景注意事项修改字符集和排序规则修改表的字符集和排序规则修改列的字符集和排序规则修改数据库的默认字符集和排序规则 3、ALTER TABLE batch_version CONVERT TO CHARACTER SET utf8mb4 C…...

C语言编程笔记:文件处理的艺术
大家好,这里是小编的博客频道 小编的博客:就爱学编程 很高兴在CSDN这个大家庭与大家相识,希望能在这里与大家共同进步,共同收获更好的自己!!! 本文目录 引言正文一、为什么要用文件二、文件的分…...
[创业之路-255]:《华为数字化转型之道》-1-主要章节、核心内容、核心思想
目录 前言:数字化转型对于企业而言,是一种全方位的变革 一、主要章节 1、认知篇(第1~2章)- Why 2、方法篇(第3~5章)- How 3、实践篇(第6~10章)- 实践 4、平台篇(第…...

《汽车维修技师》是什么级别的期刊?是正规期刊吗?能评职称吗?
问题解答: 问:《汽车维修技师》是不是核心期刊? 答:不是,是知网收录的正规学术期刊。 问:《汽车维修技师》级别? 答:省级。主管单位:北方联合出版传媒(…...

2024 京东零售技术年度总结
每一次回望,都为了更好地前行。 2024 年,京东零售技术在全面助力业务发展的同时,在大模型应用、智能供应链、端技术、XR 体验等多个方向深入探索。京东 APP 完成阶段性重要改版,打造“又好又便宜”的优质体验;国补专区…...

PyTorch使用教程(8)-一文了解torchvision
一、什么是torchvision torchvision提供了丰富的功能,主要包括数据集、模型、转换工具和实用方法四大模块。数据集模块内置了多种广泛使用的图像和视频数据集,如ImageNet、CIFAR-10、MNIST等,方便开发者进行训练和评估。模型模块封装了大量经…...
如何在不暴露MinIO地址的情况下,用Spring Boot与KKFileView实现文件预览
在现代Web应用中,文件预览是一项常见且重要的功能。它允许用户在不上传或下载文件的情况下,直接在浏览器中查看文件内容。然而,直接将文件存储服务(如MinIO)暴露给前端可能会带来安全风险。本文将介绍如何在不暴露MinI…...

ICMP协议和ICMP重定向攻击
✍作者:柒烨带你飞 💪格言:生活的情况越艰难,我越感到自己更坚强;我这个人走得很慢,但我从不后退。 📜系列专栏:网络安全从菜鸟到飞鸟的逆袭 目录 一,ICMP基本概念二&…...

leetcode203-移除链表元素
leetcode203 什么是链表 之前不懂链表的数据结构,一看到链表的题目就看不明白 链表是通过next指针来将每个节点连接起来的,题目中给的链表是单向链表,有两个值,一个val表示值,一个next:表示连接的下一个…...
Rust 中构建 RESTful API
在 Rust 中构建 RESTful API,你可以选择几个不同的框架。每个框架有不同的特点、优缺点和适用场景,下面我将介绍几个常用的 Rust Web 框架,并分析它们的优缺点。 Actix Web 简介: Actix Web 是一个非常高性能的 Web 框架…...

Sqlmap入门
原理 在owasp发布的top10 漏洞里面,注入漏洞一直是危害排名第一,其中数据库注入漏洞是危害的。 当攻击者发送的sql语句被sql解释器执行,通过执行这些恶意语句欺骗数据库执行,导致数据库信息泄漏 分类 按注入类型 常见的sql注入…...

迈向 “全能管家” 之路:机器人距离终极蜕变还需几步?
【图片来源于网络,侵删】 这是2024年初Figure公司展示的人形机器人Figure 01,他可以通过观看人类的示范视频,在10小时内经过训练学会煮咖啡,并且这个过程是完全自主没有人为干涉的! 【图片来源于网络,侵删】…...

移动端 REM 适配
移动端 REM 适配 Vant 中的样式默认使用 px 作为单位,如果需要使用 rem 单位,推荐使用以下两个工具: postcss-pxtorem 是一款 postcss 插件,用于将单位转化为 remlib-flexible 用于设置 rem 基准值 下面我们分别将这两个工具配…...
逐笔成交逐笔委托Level2高频数据下载和分析:20241230
逐笔委托逐笔成交下载 链接: https://pan.baidu.com/s/11Tdq06bbYX4ID9dEaiv_lQ?pwdcge6 提取码: cge6 Level2逐笔成交逐笔委托数据分享下载 利用Level2的逐笔交易和委托数据,这种以毫秒为单位的详细信息能揭露众多关键信息,如庄家意图、伪装行为&…...
Python爬虫实战:研究MechanicalSoup库相关技术
一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题
在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件,这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下,实现高效测试与快速迭代?这一命题正考验着…...
CSS设置元素的宽度根据其内容自动调整
width: fit-content 是 CSS 中的一个属性值,用于设置元素的宽度根据其内容自动调整,确保宽度刚好容纳内容而不会超出。 效果对比 默认情况(width: auto): 块级元素(如 <div>)会占满父容器…...

回溯算法学习
一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...

【笔记】WSL 中 Rust 安装与测试完整记录
#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统:Ubuntu 24.04 LTS (WSL2)架构:x86_64 (GNU/Linux)Rust 版本:rustc 1.87.0 (2025-05-09)Cargo 版本:cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...

MySQL 知识小结(一)
一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库,分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷,但是文件存放起来数据比较冗余,用二进制能够更好管理咱们M…...

2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)
安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...
Redis:现代应用开发的高效内存数据存储利器
一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发,其初衷是为了满足他自己的一个项目需求,即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源,Redis凭借其简单易用、…...

DBLP数据库是什么?
DBLP(Digital Bibliography & Library Project)Computer Science Bibliography是全球著名的计算机科学出版物的开放书目数据库。DBLP所收录的期刊和会议论文质量较高,数据库文献更新速度很快,很好地反映了国际计算机科学学术研…...