你的名字

C++ / Qt 桌面与图形软件开发 · 12 年架构经验

可在线运行的项目

网络拓扑编辑器 / 监控台

Qt 6 · Graphics View · 同一套代码编译桌面版和 WebAssembly 版

节点拖拽、连线、框选、对齐、撤销重做,属性面板直接编辑, 告警模拟实时闪烁,鸟瞰图导航,JSON 导入导出。 内置压力测试:一键生成 20000 个节点,可以开关 LOD 和 BSP 索引对比单帧耗时。

技术要点

两万节点保持流畅

  • BspTreeIndex 场景索引 + 视口裁剪,只绘制可见图元
  • levelOfDetailFromTransform 三级 LOD:缩小后节点退化为色块,不画文字和图标
  • 节点不继承 QObject,每个节点省下信号槽的内存开销
  • 视图开启 DontSavePainterState,图元自己保证画笔状态

局部刷新而不是整屏重绘

  • 告警闪烁由场景里唯一的定时器驱动,只刷新告警节点
  • 节点移动时只调整与它相连的连线(ItemPositionHasChanged)
  • 鸟瞰图共享同一个 scene,NoViewportUpdate + 标脏后定时刷新
  • 告警日志按周期批量插入,一次 beginInsertRows

完整的撤销重做

  • 添加、删除、移动、连线、改属性、对齐全部走 QUndoStack
  • 删除节点时连带记录相关连线,撤销后完整恢复
  • 方向键微调用 mergeWith 合并成一条命令
  • 明确图元所有权规则,撤销栈析构时不会重复释放

Model/View

  • 属性面板:自定义 QAbstractTableModel + Delegate,按属性类型创建下拉框/数值框/带校验的输入框
  • 编辑结果生成撤销命令,而不是直接改数据
  • 告警日志:QSortFilterProxyModel 按级别和关键字过滤,双击定位节点

一套代码,桌面 + Web

  • 平台差异只在文件读写,用 #ifdef Q_OS_WASM 隔离
  • Web 版用 getOpenFileContent / saveFileContent 读写本地文件
  • 不使用 exec() 模态循环,对话框全部用 open()
  • 中文字体子集打包进 qrc(约 800KB),解决 WASM 无系统字体的问题

工程化与部署

  • 多阶段 Dockerfile:emsdk + Qt 工具链 → 编译 → nginx
  • wasm 构建时 gzip 预压缩,nginx gzip_static 直接发送
  • docker compose 部署,可叠加 Caddy 自动 HTTPS

技术栈

语言C++17、CMake
框架Qt 6.8 LTS:Widgets、Graphics View、Model/View、Undo
平台Windows / Linux 桌面,浏览器(WebAssembly)