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

Qt 5.14实战:用QGraphicsView打造可交互的2D绘图工具(附完整代码)

Qt 5.14实战用QGraphicsView打造可交互的2D绘图工具附完整代码1. 项目概述与核心组件在Qt框架中构建2D绘图工具时QGraphicsView架构提供了完美的解决方案。这个架构由三个核心类组成QGraphicsScene作为图形项的容器管理所有可绘制对象QGraphicsView可视化场景的窗口部件处理用户交互QGraphicsItem所有图形元素的基类如矩形、椭圆等// 基础架构示例 QGraphicsScene *scene new QGraphicsScene(this); QGraphicsView *view new QGraphicsView(scene); view-setRenderHint(QPainter::Antialiasing); // 启用抗锯齿1.1 场景设置最佳实践创建场景时应考虑以下关键参数参数推荐值说明场景尺寸800x600适中大小可容纳多个图形背景色Qt::white标准绘图背景索引算法BspTreeIndex适合静态图形项的快速查找// 场景初始化代码 scene-setSceneRect(0, 0, 800, 600); scene-setBackgroundBrush(Qt::white); scene-setItemIndexMethod(QGraphicsScene::BspTreeIndex);2. 基础绘图功能实现2.1 添加基本图形项Qt提供了多种内置图形项类型// 添加矩形 QGraphicsRectItem *rect scene-addRect(50, 50, 100, 100, QPen(Qt::blue), QBrush(Qt::yellow)); // 添加椭圆 QGraphicsEllipseItem *ellipse scene-addEllipse(200, 50, 100, 100, QPen(Qt::red), QBrush(Qt::green)); // 添加文本 QGraphicsTextItem *text scene-addText(Hello Qt!); text-setPos(350, 80);2.2 实现选择与移动通过设置视图的拖拽模式实现不同交互// 在构造函数中设置 view-setDragMode(QGraphicsView::RubberBandDrag); // 矩形选择 // 或 view-setDragMode(QGraphicsView::ScrollHandDrag); // 手掌拖动提示要为特定图形项启用移动需要设置标志item-setFlag(QGraphicsItem::ItemIsMovable, true);3. 高级交互功能3.1 自定义绘图工具创建绘图工具类实现自由绘制class DrawingTool : public QObject { Q_OBJECT public: DrawingTool(QGraphicsScene *scene) : m_scene(scene) {} protected: void mousePressEvent(QGraphicsSceneMouseEvent *event) override { m_path new QGraphicsPathItem(); m_scene-addItem(m_path); // 初始化路径... } void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override { // 更新路径... } private: QGraphicsScene *m_scene; QGraphicsPathItem *m_path; };3.2 视图变换控制实现缩放和旋转功能# 缩放示例Python版C类似 def wheelEvent(self, event): factor 1.2 if event.angleDelta().y() 0 else 1/1.2 self.scale(factor, factor) # 旋转示例 def rotateView(self, angle): self.rotate(angle)3.3 右键菜单实现为图形项添加上下文菜单void CustomItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { QMenu menu; QAction *deleteAction menu.addAction(Delete); connect(deleteAction, QAction::triggered, [this]() { scene()-removeItem(this); delete this; }); menu.exec(event-screenPos()); }4. 性能优化技巧4.1 缓存策略对比缓存模式适用场景内存消耗NoCache动态变化项低ItemCoordinateCache静态复杂项中DeviceCoordinateCache高DPI显示高// 为图形项设置缓存 item-setCacheMode(QGraphicsItem::ItemCoordinateCache);4.2 渲染优化参数// 视图优化设置 view-setOptimizationFlags( QGraphicsView::DontSavePainterState | QGraphicsView::DontAdjustForAntialiasing); // 视口更新模式 view-setViewportUpdateMode(QGraphicsView::SmartViewportUpdate);5. 完整示例代码以下是核心功能的实现框架#include QtWidgets class DrawingView : public QGraphicsView { public: DrawingView(QWidget *parent nullptr) : QGraphicsView(parent) { setScene(new QGraphicsScene(this)); setRenderHint(QPainter::Antialiasing); setDragMode(RubberBandDrag); // 添加示例图形 scene()-addRect(100, 100, 200, 100, QPen(Qt::black), QBrush(Qt::cyan)); // 安装事件过滤器 scene()-installEventFilter(this); } protected: bool eventFilter(QObject *obj, QEvent *event) override { if (event-type() QEvent::GraphicsSceneMousePress) { auto mouseEvent static_castQGraphicsSceneMouseEvent*(event); if (mouseEvent-button() Qt::LeftButton) { // 处理绘图逻辑 } } return QGraphicsView::eventFilter(obj, event); } void wheelEvent(QWheelEvent *event) override { scaleView(pow(2., event-angleDelta().y() / 240.0)); } private: void scaleView(qreal factor) { qreal currentScale transform().m11(); if ((factor 1 currentScale 0.1) || (factor 1 currentScale 10)) return; scale(factor, factor); } }; int main(int argc, char *argv[]) { QApplication app(argc, argv); DrawingView view; view.setWindowTitle(Qt绘图工具); view.resize(800, 600); view.show(); return app.exec(); }6. 常见问题解决方案6.1 图形项闪烁问题原因频繁重绘整个视图解决// 1. 设置智能更新模式 view-setViewportUpdateMode(QGraphicsView::SmartViewportUpdate); // 2. 为静态项启用缓存 item-setCacheMode(QGraphicsItem::ItemCoordinateCache);6.2 内存泄漏排查使用Qt工具检测# 在程序退出时检查内存泄漏 export QT_DEBUG_PLUGINS1 valgrind --toolmemcheck ./your_app6.3 跨平台兼容性需要注意不同系统的DPI处理字体渲染差异图形加速支持// 高DPI支持 view-setAttribute(Qt::WA_AcceptTouchEvents); QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);7. 扩展功能思路Undo/Redo框架集成QUndoStack实现历史记录图层管理通过QGraphicsItemGroup实现分层绘制导入导出支持SVG、PNG等格式自定义图形项继承QGraphicsItem创建特殊图形// 自定义图形项示例 class CustomItem : public QGraphicsItem { public: QRectF boundingRect() const override { return QRectF(-50, -50, 100, 100); } void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override { painter-drawEllipse(-50, -50, 100, 100); } };在实际项目中根据需求逐步添加这些功能模块可以构建出功能强大的专业绘图工具。

相关文章:

Qt 5.14实战:用QGraphicsView打造可交互的2D绘图工具(附完整代码)

Qt 5.14实战:用QGraphicsView打造可交互的2D绘图工具(附完整代码) 1. 项目概述与核心组件 在Qt框架中构建2D绘图工具时,QGraphicsView架构提供了完美的解决方案。这个架构由三个核心类组成: QGraphicsScene&#xff1a…...

ICESat-2激光测高仪ATLAS实战指南:如何利用多光束提升地形测量精度

ICESat-2激光测高仪ATLAS实战指南:如何利用多光束提升地形测量精度 当我们需要从太空精确测量地球表面的高度时,传统卫星遥感技术往往面临诸多挑战。云层遮挡、植被覆盖、复杂地形等因素都会影响测量结果的准确性。NASA的ICESat-2卫星搭载的ATLAS系统&am…...

实战笔记:解锁Unity WebGL在移动端的运行限制

1. 为什么Unity默认屏蔽移动端WebGL运行 Unity官方在WebGL构建选项中默认屏蔽移动端运行并非没有道理。我曾在项目中尝试过直接让WebGL内容跑在手机浏览器里,结果发现帧率直接掉到个位数。这主要是因为手机浏览器和PC浏览器在硬件加速、内存管理等方面存在巨大差异。…...

CoPaw赋能前端开发:JavaScript实现实时数据可视化大屏

CoPaw赋能前端开发:JavaScript实现实时数据可视化大屏 1. 开篇:当AI遇到数据可视化 最近在做一个电商运营监控项目时,遇到了一个棘手问题:后台每天产生上百万条用户行为数据,但传统的静态报表根本无法实时反映业务状…...

告别繁琐脚本:用油猴一站式搞定B站音视频下载与合成

1. 为什么你需要油猴脚本下载B站音视频 每次在B站看到喜欢的视频或音乐,想保存下来反复欣赏时,你是不是也遇到过这些烦恼?传统方法要么需要安装复杂的Python环境,要么得面对各种API接口变动,甚至还要手动合成音视频文件…...

如何选择最适合的LLM评估指标?从ROUGE到BERTScore的全面解析

1. 为什么LLM评估指标如此重要? 当你训练了一个语言模型,或者使用现成的API生成文本时,最头疼的问题往往是:这个结果到底好不好?这个问题看似简单,但实际上非常复杂。就像考试评分一样,不同的评…...

语言清洗运动:禁用‘if/else‘第一年——软件测试从业者的专业反思与策略

运动背景与测试行业的转折点语言清洗运动源于2025年全球编程社区的共识,旨在通过禁用传统条件语句(如if/else)来简化代码结构、减少分支错误,并推动函数式编程范式的普及。作为软件测试从业者,我们亲历了这一禁令实施的…...

ZYNQ7100板级原理图设计实战:从入门到精通

1. ZYNQ7100硬件设计入门指南 第一次接触ZYNQ7100这块开发板时,我和大多数硬件工程师一样有点懵——这玩意儿既有ARM处理器又有FPGA,原理图该怎么画?后来在几个实际项目中摸爬滚打,才发现掌握几个关键点就能轻松上手。XC7Z100-2FF…...

2023年国赛-大数据应用开发(师生同赛)_Flink实时计算与Kafka数据流处理实战解析

1. Flink实时计算与Kafka数据流处理入门指南 第一次接触Flink和Kafka的时候,我被它们处理实时数据的能力震撼到了。想象一下,你打开水龙头,水流源源不断地涌出,而Flink就像是一个超级智能的水处理系统,能够实时过滤、分…...

【硬件相关】IB网与以太网核心技术解析及高性能网络部署指南

1. Infiniband与以太网的技术本质差异 第一次接触高性能网络时,我被各种专业术语搞得晕头转向。直到亲手调试了Mellanox ConnectX-4和Intel E810这两块网卡后,才真正理解IB网和以太网的本质区别。简单来说,这就像赛车和家用轿车的差异——虽然…...

从零开始玩转ESP32:VSCode插件配置与LED闪烁项目实战

从零开始玩转ESP32:VSCode插件配置与LED闪烁项目实战 第一次接触ESP32开发板时,那种既兴奋又忐忑的心情至今记忆犹新。这块小小的开发板蕴藏着无限可能,但如何快速搭建开发环境却让不少新手望而却步。本文将带你绕过那些我踩过的坑&#xff0…...

ECharts高级玩法:用SVG自定义你的专属数据标记

ECharts高级玩法:用SVG自定义你的专属数据标记 在数据可视化领域,ECharts凭借其强大的功能和灵活的配置选项,已经成为前端开发者的首选工具之一。但当你已经熟练掌握了基础图表配置后,是否曾想过如何让数据标记不再局限于系统预设…...

AI人体骨骼关键点检测场景应用:安防监控、人机交互案例分享

AI人体骨骼关键点检测场景应用:安防监控、人机交互案例分享 1. 引言:从实验室到现实世界 想象一下,一个普通的摄像头,不仅能“看见”画面,还能“理解”画面中人的一举一动。它能判断一个人是在正常行走,还…...

实测Qwen3-1.7B:快速部署体验阿里最新开源大模型

实测Qwen3-1.7B:快速部署体验阿里最新开源大模型 1. Qwen3-1.7B模型简介 Qwen3(千问3)是阿里巴巴集团于2025年4月29日开源的新一代通义千问大语言模型系列。作为该系列中的轻量级选手,Qwen3-1.7B拥有17亿参数,在保持…...

PLUS-InVEST模型耦合下的多情景土地利用优化与生态系统服务协同提升策略

1. PLUS-InVEST模型耦合的核心价值 当我们在讨论土地利用规划时,最头疼的问题就是如何在生态保护和经济发展之间找到平衡点。传统方法往往像盲人摸象,要么过度依赖历史经验,要么只能做简单的线性预测。而PLUS-InVEST这对黄金组合,…...

OpenCore Legacy Patcher零基础高效制作macOS启动盘指南

OpenCore Legacy Patcher零基础高效制作macOS启动盘指南 【免费下载链接】OpenCore-Legacy-Patcher 体验与之前一样的macOS 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher 还在为旧Mac无法升级最新系统而烦恼?OpenCore Legacy …...

开源代码示例:JS如何基于百度WebUploader实现局域网Word文档的文件夹分片上传源码?

第一章:毕业设计の终极挑战 "同学,你这毕业设计要做文件管理系统?还要支持10G大文件上传?"导师推了推眼镜,我仿佛看到他头顶飘着"这届学生真难带"的弹幕。 "是的老师!还要兼容I…...

ChatGLM3-6B在智能写作辅助中的应用

ChatGLM3-6B在智能写作辅助中的应用 1. 写作场景的现实困境与破局思路 你有没有过这样的经历:面对空白文档,光是写个开头就卡了半小时;赶着交营销方案时,反复修改却总觉得文案不够抓人;技术文档写到一半,…...

nanobot效果展示:仅4000行代码,实现媲美大模型的智能回复

nanobot效果展示:仅4000行代码,实现媲美大模型的智能回复 1. 初见nanobot:颠覆认知的“小身材,大智慧” 当我第一次听说一个只有4000行代码的AI助手时,我的第一反应是怀疑。毕竟,现在动辄数十万、上百万行…...

电商运营必备:RMBG-2.0一键移除商品背景,1秒出透明图

电商运营必备:RMBG-2.0一键移除商品背景,1秒出透明图 1. 电商运营的痛点:背景处理耗时耗力 在电商运营的日常工作中,商品图片的背景处理是一个无法回避但又极其耗时的环节。传统方法通常需要: 使用Photoshop手动抠图…...

Phi-3-vision-128k-instruct 开发环境搭建:从GitHub克隆到IDEA调试全流程

Phi-3-vision-128k-instruct 开发环境搭建:从GitHub克隆到IDEA调试全流程 1. 准备工作与环境检查 在开始之前,我们需要确保本地开发环境满足基本要求。首先确认你的IntelliJ IDEA版本为2021.3或更高,Python插件已安装并启用。同时&#xff…...

PCIe Switch PM40028启动问题排查与解决

1. PM40028芯片启动问题初探 最近在项目中用到了Microchip的PCIe Gen4 Switch芯片PM40028,这款芯片主要用于高速数据交换场景。按照常规流程,我们参考了Demo板设计电路,完成PCB打样后,首先进行了基础硬件测量。电源电压、纹波、上…...

从算法到实战:深度剖析IDA、Ghidra与Cutter在逆向工程中的核心差异

1. 逆向工程工具的三国演义:为什么选择IDA、Ghidra和Cutter 逆向工程就像拆解一台精密的钟表,我们需要透过机器码的表象,理解程序真正的运行逻辑。而反汇编工具就是我们的放大镜和解剖刀。在众多工具中,IDA Pro、Ghidra和Cutter形…...

AIGlasses_for_navigation企业级应用:对接政务无障碍数据平台API实践

AIGlasses_for_navigation企业级应用:对接政务无障碍数据平台API实践 1. 引言:从智能导航到数据赋能 想象一下,一位视障朋友正走在陌生的街道上。他佩戴的智能眼镜通过摄像头“看到”了前方的盲道,并通过语音提示他:…...

UltraISO应用:Qwen3-ASR-1.7B系统镜像制作教程

UltraISO应用:Qwen3-ASR-1.7B系统镜像制作教程 1. 为什么需要一个语音识别专用启动U盘 你有没有遇到过这样的情况:在客户现场调试语音识别系统时,临时找台电脑安装CUDA、PyTorch、vLLM和Qwen3-ASR模型,结果卡在驱动兼容性上一小…...

手把手教你用QT MQTT Client实现物联网设备通信(附完整测试记录)

手把手教你用QT MQTT Client实现物联网设备通信(附完整测试记录) 在物联网技术蓬勃发展的今天,MQTT协议凭借其轻量级、高效率的特点,已成为设备间通信的首选方案。而QT作为跨平台的C开发框架,其MQTT客户端模块为开发者…...

5步打造旧Mac复活神器:OpenCore Legacy Patcher启动盘制作全攻略

5步打造旧Mac复活神器:OpenCore Legacy Patcher启动盘制作全攻略 【免费下载链接】OpenCore-Legacy-Patcher 体验与之前一样的macOS 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher 随着macOS系统不断更新,许多旧款M…...

LightOnOCR-2-1B与Token技术结合:文档安全访问控制

LightOnOCR-2-1B与Token技术结合:文档安全访问控制 1. 企业文档安全面临的挑战 在企业日常运营中,文档处理是不可或缺的环节。从合同协议到财务报表,从技术文档到客户资料,这些文件往往包含敏感信息。传统的文档处理系统面临着一…...

虚拟机Secure Boot实战:从密钥生成到安全启动全流程

1. Secure Boot基础概念与虚拟机环境优势 Secure Boot这项技术本质上是一套数字签名验证机制,它会在系统启动的每个环节检查加载的代码是否经过可信机构签名。想象一下这就像进地铁站时的安检流程——每个乘客(可执行文件)都必须出示有效证件…...

Halcon工业视觉实战:基于模板匹配与仿射变换的螺丝精准检测方案

1. 工业视觉中的螺丝检测为什么这么难? 在自动化生产线上,螺丝检测看似简单实则暗藏玄机。我经手过十几个螺丝检测项目,最头疼的就是产线上的螺丝会以各种刁钻角度出现,有时候还会遇到反光、遮挡、油污干扰。传统方法用OpenCV写规…...