Qt节点编辑器设计与实现:动态编辑与任务流可视化(一)

文章目录

    • 一、项目概述
    • 二、整体架构:模型-视图分离的设计哲学
      • 1. 模型层:数据与业务逻辑的核心
      • 2. 视图层:图形渲染与用户交互
      • 3. 交互层:连接模型与视图的桥梁
    • 三、核心模块解析
      • 1. 样式管理系统:视觉表现的基石
      • 2. 图形数据模型:数据与关系的核心载体
      • 3. 节点交互与几何计算
      • 4. 跨平台与模块化设计
    • 四、实战示例:任务流配置与加载
    • 五、总结

在这里插入图片描述
在这里插入图片描述
Qt节点编辑器设计与实现:动态编辑与任务流可视化(一)
深入解析Qt节点编辑器框架:交互逻辑与样式系统(二)
深入解析Qt节点编辑器框架:数据流转与扩展机制(三)
深入解析Qt节点编辑器框架:高级特性与性能优化(四)

  • 本项目是由Qt开源项目NodeEditor二次开发而来,项目地址,这是个非常不错的项目,熟悉并了解它对自身与Qt画板框架的使用会有很大提升。

一、项目概述

该节点编辑器旨在提供简单易用的任务流可视化编辑功能,支持节点自由布局、动态状态设置与流程连接管理。从代码结构来看,系统采用模块化设计,主要包含样式管理、图形数据模型、节点交互逻辑等核心模块,基于Qt框架实现跨平台兼容,可广泛应用于工作流设计、数据处理流程编排等场景。
包含核心功能如下:

  1. 节点编辑:支持节点的添加、删除、移动、调整大小、动态端口、动态变量等操作。
  2. 连接编辑:支持连接的创建、删除、标签编辑等操作。。
  3. 画板操作:支持撤销、重做、复制、粘贴、旋转、缩放、筛选节点等操作。
  4. 动态样式:支持节点、连接线与画板的动态样式设置,如颜色、字体、边框等。
  5. 菜单栏操作:支持文件操作新建、打开、保存、导出图片等。
  6. 保存与加载:支持将当前任务流保存为文件,后续可加载编辑。
  7. 任务流加载:支持通过通信动态加载节点与连接线,从而达到任务流显示效果。

二、整体架构:模型-视图分离的设计哲学

该框架严格遵循模型-视图(Model-View) 设计模式,将数据逻辑与图形展示解耦,这是处理复杂交互场景的关键。

1. 模型层:数据与业务逻辑的核心

模型层由AbstractGraphModel(抽象基类)和DataFlowGraphModel(具体实现)构成,负责管理节点、连接的核心数据与业务规则:

  • 节点数据:包括节点类型、端口信息、位置尺寸、内部状态等。
  • 连接数据:以ConnectionId(包含源节点、源端口、目标节点、目标端口)唯一标识一条连接,维护连接的有效性规则。
  • 业务逻辑:如连接是否允许创建(类型匹配、无循环)、端口动态增删时的连接调整等。

代码中,DataFlowGraphModel通过_models(存储节点实例)和_connectivity(存储连接ID集合)管理核心数据,对外提供addNodeaddConnection等接口,确保数据操作的一致性。

2. 视图层:图形渲染与用户交互

视图层由BasicGraphicsSceneDataFlowGraphicsScene等场景类,以及NodeGraphicsObjectConnectionGraphicsObject等图形对象类构成:

  • 场景类:继承自QGraphicsScene,负责管理所有图形对象的生命周期,处理全局事件(如右键菜单、保存加载)。
  • 图形对象类:继承自QGraphicsItem,负责单个节点/连接的渲染(如节点样式、连接线条)和局部交互(如拖拽、点击)。

例如,BasicGraphicsScenetraverseGraphAndPopulateGraphicsObjects方法会遍历模型中的节点和连接,创建对应的图形对象,实现模型到视图的初始同步。

3. 交互层:连接模型与视图的桥梁

交互层通过信号槽机制实现模型与视图的实时同步:

  • 模型变化时(如nodeCreatedconnectionDeleted),发送信号通知视图更新图形对象。
  • 视图接收用户操作(如拖拽节点、创建连接),通过命令模式(QUndoStack)修改模型,确保操作可撤销。

代码中,BasicGraphicsScene在构造函数中连接了模型的多个信号(如connectionCreatedonConnectionCreated),保证视图能及时响应模型变化。

三、核心模块解析

1. 样式管理系统:视觉表现的基石

节点编辑器的视觉体验直接影响用户交互效率,该系统通过NodeStyleConnectionStyleStyleCollection构建了灵活的样式管理机制。

  • 多状态样式支持NodeStyle类通过_styleData字典存储不同状态(如正常、选中、错误)的样式配置,包括边界颜色、渐变颜色、阴影效果等。例如,在加载JSON配置时,既支持兼容旧版本的默认样式,也支持多状态样式定义:

    // 多状态样式加载逻辑
    for (auto it = nodeStyleObj.begin(); it != nodeStyleObj.end(); ++it) {QString state = it.key();QJsonObject stateObj = it.value().toObject();NodeStyleData data;// 解析颜色、尺寸等属性..._styleData[state] = data;
    }
    
  • JSON序列化与反序列化:样式配置支持从JSON文件/文本加载,也可导出为JSON,便于配置共享与保存。颜色解析通过parseColor辅助函数实现,支持RGB数组与十六进制字符串两种格式,提升配置灵活性。

  • 全局样式管理StyleCollection作为单例模式,统一管理节点、连接与视图的样式,提供setNodeStyle等方法实现全局样式切换,确保界面风格一致性。

2. 图形数据模型:数据与关系的核心载体

图形数据模型是节点编辑器的"大脑",负责管理节点、连接及其关系。系统通过AbstractGraphModelStandardModelDataFlowGraphModel构建了层次化的模型体系。

  • 节点与连接管理StandardModel实现了节点的增删、连接的创建与删除等基础功能。通过_models存储节点实例,_connectivity维护连接关系,支持allNodeIdsconnections等方法查询数据:

    // 节点添加逻辑
    NodeId StandardModel::addNode(QString const nodeType) {std::unique_ptr<NodeDelegateModel> model = _registry->create(nodeType);if (model) {NodeId newId = newNodeId();_models[newId] = std::move(model);Q_EMIT nodeCreated(newId);return newId;}return InvalidNodeId;
    }
    
  • 动态端口处理:节点端口的动态增删是高级功能,AbstractGraphModel通过portsAboutToBeDeletedportsInserted等方法,在端口变化时自动调整关联连接,避免连接失效:

    // 端口删除前处理关联连接
    void AbstractGraphModel::portsAboutToBeDeleted(...) {for (PortIndex portIndex = first; portIndex <= clampedLast; ++portIndex) {std::unordered_set<ConnectionId> conns = connections(nodeId, portType, portIndex);for (auto connectionId : conns) {deleteConnection(connectionId);}}
    }
    
  • 连接合法性检查DataFlowGraphModel在创建连接时,通过connectionPossible方法检查数据类型匹配、端口是否可用及是否存在循环依赖,确保流程逻辑正确:

    // 无环检查(深度优先遍历)
    auto hasLoops = [this, &connectionId]() -> bool {std::stack<NodeId> filo;filo.push(connectionId.inNodeId);while (!filo.empty()) {auto id = filo.top();filo.pop();if (id == connectionId.outNodeId) return true; // 发现循环// 递归检查下游节点}return false;
    };
    

3. 节点交互与几何计算

节点的交互体验依赖于精准的几何计算,AbstractNodeGeometry类封装了端口位置计算、碰撞检测等核心逻辑:

  • 端口位置计算portScenePosition方法结合节点变换矩阵,计算端口在场景中的绝对位置,为连接绘制提供坐标基础。

  • 端口碰撞检测checkPortHit通过计算鼠标位置与端口的距离,判断是否点击端口,支持用户发起连接操作:

    PortIndex AbstractNodeGeometry::checkPortHit(...) const {double const tolerance = 2.0 * nodeStyle.getNodeStyleData(nodeState).ConnectionPointDiameter;for (unsigned int portIndex = 0; portIndex < n; ++portIndex) {auto pp = portPosition(nodeId, portType, portIndex);QPointF p = pp - nodePoint;auto distance = std::sqrt(QPointF::dotProduct(p, p));if (distance < tolerance) return portIndex;}return InvalidPortIndex;
    }
    

4. 跨平台与模块化设计

系统通过Compiler.hppExport.hpp实现跨平台兼容,支持MinGW、Clang、MSVC等主流编译器,并通过宏定义统一动态库导出/导入逻辑:

// 跨平台导出宏定义
#ifdef NODE_EDITOR_PLATFORM_WINDOWS
#define NODE_EDITOR_EXPORT __declspec(dllexport)
#define NODE_EDITOR_IMPORT __declspec(dllimport)
#elif NODE_EDITOR_COMPILER_GNU_VERSION_MAJOR >=4 || defined(NODE_EDITOR_COMPILER_CLANG)
#define NODE_EDITOR_EXPORT __attribute__((visibility("default")))
#endif

节点数据处理采用模块化设计,MathOperationDataModelDecimalData展示了如何实现具体节点逻辑(如数值计算),通过setInData接收输入、compute处理数据、outData输出结果,便于扩展新节点类型。

四、实战示例:任务流配置与加载

MainWidget中的test方法展示了如何通过JSON配置初始化任务流,这是我随意模拟的数据,实际上的数据应该是通信数据解析而来。示例JSON包含节点(如"星期一"、“上班”)与连接关系,加载后通过定时器动态更新数据,模拟任务流的运行状态:

// 从JSON字符串加载任务流
QJsonDocument doc = QJsonDocument::fromJson(jsonString.toUtf8());
m_jsonObj = doc.object();
// 定时器更新数据
m_testTimer->start(1000);

五、总结

  • 本身也就是为了学习更加深入的Qt画板框架,所以项目开源
  • 节点编辑器框架的设计与实现,从基础到高级,覆盖了模型-视图分离、交互逻辑、数据流转、扩展机制等多个方面。
  • 框架的核心技术点包括模型-视图分离、命令模式、信号槽机制、类型安全的传递机制、依赖驱动的更新逻辑、惰性计算、抽象接口与工厂模式、序列化等。
  • 框架的优势在于其高度的可定制性、可扩展性、可维护性。
  • 框架的应用场景包括可视化编程、数据处理流水线、工业控制流程图等。
  • 未来可进一步优化的方向包括分布式节点计算(跨进程/网络)、节点性能分析工具、AI辅助节点推荐等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/95148.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/95148.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL常见报错分析及解决方案总结(4)---ERROR 1040(00000):Too many connections

报错信息&#xff1a;ERROR 1040(00000):Too many comnections异常效果&#xff1a;原因分析&#xff1a;“ERROR 1040 (00000): Too many connections” 是 MySQL 数据库最常见的连接数超限错误&#xff0c;本质是 “当前试图连接数据库的客户端数量&#xff0c;超过了 MySQL …

GRPO(组相对策略优化):大模型强化学习的高效进化

本文由「大千AI助手」原创发布&#xff0c;专注用真话讲AI&#xff0c;回归技术本质。拒绝神话或妖魔化。搜索「大千AI助手」关注我&#xff0c;一起撕掉过度包装&#xff0c;学习真实的AI技术&#xff01; ✨ 1. GRPO概述&#xff1a;重新定义大模型强化学习效率 GRPO&#x…

【Canvas与戳记】蓝底黄面十六角Premium Quality戳记

【成图】【代码】<!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>蓝底黄面十六角Premium Quality戳记 Draft1</title><style ty…

深度学习:洞察发展趋势,展望未来蓝图

在科技飞速发展的当下&#xff0c;深度学习作为人工智能领域的璀璨明星&#xff0c;正以前所未有的速度重塑着各个行业的格局。从日常使用的智能语音助手&#xff0c;到医疗领域精准的疾病诊断&#xff0c;再到自动驾驶汽车对复杂路况的实时感知与决策&#xff0c;深度学习无处…

基于Docker部署的Teable应用

简介Teable 是一款高性能多维表格本地化的解决方案&#xff0c;通过无代码方式快速构建业务管理系统&#xff0c;支持私有部署和精细权限管理。对于个人或者小团队使用&#xff0c;可以避免昂贵的集成软件带来的成本压力。特点Excel 式任意拖拽选区编辑支持双向关联&#xff0c…

Java项目实现【记录系统操作日志】功能

✨ 哈喽&#xff0c;屏幕前的每一位开发者朋友&#xff0c;你们好呀&#xff01;✨​ 当你点开这篇文章时&#xff0c;或许正对着 IDE 里闪烁的光标发呆&#xff0c;或许刚解决一个卡了三天的 bug&#xff0c;正端着咖啡松口气 —— 不管此刻的你在经历什么&#xff0c;都想先和…

响应式编程框架Reactor【4】

文章目录七、调度与线程模型7.1 概述7.2 Scheduler: Reactor 的线程调度器7.3 两大核心操作符&#xff1a;subscribeOn vs publishOn7.4 示例详解7.4.1 subscribeOn()的全局影响7.4.2 publishOn() 的局部切换7.4.3 多个publishOn切换7.4.4 线程切换时序图7.5 核心调度器7.5.1 B…

第21节:环境贴图与PBR材质升级——构建电影级真实感渲染

第21节&#xff1a;环境贴图与PBR材质升级——构建电影级真实感渲染 概述 基于物理的渲染&#xff08;Physically Based Rendering, PBR&#xff09;是当代计算机图形学中最重要的技术进步之一&#xff0c;它彻底改变了实时渲染的质量标准。在本节中&#xff0c;我们将深入探索…

【ROS2】ROS2 基础学习教程 、movelt学习

主要博主 参考资料&#xff1a; ROS系列&#xff1a; b站荔枝橙 b战哈萨克斯坦x 《ROS 2机器人开发从入门到实践》6.2.2 在RViz中显示机器人_哔哩哔哩_bilibili 动手学ROS2–鱼香肉丝 ​​​​​​​ 古月居ros2教程 北京华清智能科技 ros教程 moveit系列&#xff1a; 爱喝青…

Java类加载与JVM详解:从基础到双亲委托机制

在Java开发中&#xff0c;理解JVM&#xff08;Java虚拟机&#xff09;和类加载机制是掌握高级特性的关键。本文将从JDK、JRE、JVM的关系入手&#xff0c;深入讲解JVM的内存结构&#xff0c;并详细剖析类加载的全过程&#xff0c;包括加载时机、流程以及核心机制——双亲委托模型…

准备机试--图【y总版】[重要]【最短路】

常用代码模板3——搜索与图论 - AcWing 一般&#xff0c;稀疏图&#xff08;m约等于n&#xff09;:堆优化版本的dj&#xff1b;稠密图&#xff08;mn^2&#xff09;&#xff1a;朴素dj 最短路的难点在于建图【抽象出点和边】 朴素dj

Python API接口实战指南:从入门到精通

&#x1f31f; Hello&#xff0c;我是蒋星熠Jaxonic&#xff01; &#x1f308; 在浩瀚无垠的技术宇宙中&#xff0c;我是一名执着的星际旅人&#xff0c;用代码绘制探索的轨迹。 &#x1f680; 每一个算法都是我点燃的推进器&#xff0c;每一行代码都是我航行的星图。 &#x…

Spring和mybatis整合后事务拦截器TransactionInterceptor开启提交事务流程

目录一、说明二、TransactionInterceptor开启事务&#xff08;1&#xff09;、拦截方法&#xff08;2&#xff09;、开启事务绑定数据库连接&#xff08;3&#xff09;、mybatis中sql执行数据库连接获取&#xff08;4&#xff09;、事务提交和当前线程ThreadLocal清理&#xff…

05.《ARP协议基础知识探秘》

ARP协议基本介绍与实践 文章目录**ARP协议基本介绍与实践**ARP概述ARP报文类型ARP工作过程解析ARP工作原理示意图无故ARP/免费ARP实验案例**实验目标**实验环境实验步骤ARP概述 作用&#xff1a;ARP&#xff08;Address Resolution Protocol&#xff0c;地址解析协议&#xff…

互联网大厂面试:大模型应用开发岗位核心技术点解析

互联网大厂面试&#xff1a;大模型应用开发岗位核心技术点解析 第一轮&#xff1a;大模型基础与上下文工程 问题 1&#xff1a;你能简单介绍 Transformer 架构的工作原理吗&#xff1f; 小C&#xff1a;嗯&#xff0c;我理解是 Transformer 主要依赖自注意力机制&#xff08;Se…

【深度学习新浪潮】有没有什么方法可以将照片变成线描稿,比如日式漫画的那种?

一、技术原理与研究进展 1. 线描生成的核心技术路径 传统方法:基于边缘检测(如Canny算子)和形态学操作,但难以处理复杂纹理和艺术风格。 深度学习方法: 端到端生成:使用U-Net架构(如ArtLine项目)直接学习照片到线描的映射,结合自注意力机制和感知损失提升细节保留能力…

NV032NV037美光固态闪存NV043NV045

NV032NV037美光固态闪存NV043NV045在数字化浪潮席卷全球的当下&#xff0c;存储技术的每一次突破都深刻影响着从个人消费到企业级应用的各个领域。美光科技作为行业领军者&#xff0c;其NV系列固态闪存产品始终以技术创新为核心驱动力。本文将聚焦NV032、NV037、NV043、NV045四…

天硕G40工业固态硬盘破解轨道存储难题

在高铁与轨道交通高速发展的今天&#xff0c;轨道检测探伤是保障列车安全运行的核心环节。据统计&#xff0c;我国铁路总里程已突破16万公里&#xff0c;日均检测数据量超10TB。加固平板一体机作为轨道探伤领域的“移动工作站”&#xff0c;需要在跨越大江南北的极端环境中实时…

基于Velero + 阿里云 OSS的Kubernetes 集群的备份与恢复

在 Kubernetes&#xff08;K8s&#xff09;中&#xff0c;备份和恢复是保障数据安全与业务连续性的关键环节&#xff0c;主要方式包括 ETCD 备份恢复 和 Velero 备份恢复&#xff0c;两者在备份粒度、恢复影响范围、存储位置等方面存在以下差异&#xff1a; 1、ETCD 备份恢复&…

解构与重构:“真人不露相,露相非真人” 的存在论新解 —— 论 “真在” 的行为表达本质

解构与重构&#xff1a;“真人不露相&#xff0c;露相非真人” 的存在论新解 —— 论 “真在” 的行为表达本质绪论&#xff1a;传统解释的突围 —— 从 “藏才” 到 “存真”“真人不露相&#xff0c;露相非真人” 这句谚语&#xff0c;自明代《西游记》以降&#xff0c;便长期…