# 当前开发交接 > 更新日期:2026-08-22。本文件只保留当前状态和下一步;完成事项合并成结论,不追加按日期排列的开发流水账。 ## 当前状态 - 分支:`main` - 核心软件闭环已经可用:HMI 编辑、结构化梯形图、离线仿真、工程 JSON、统一运行监控大屏、自由监控和 Modbus RTU 真机读写均已实现 - HMI 外观属性和梯形图十列可选插入网格均已按逻辑完成提交;开始工作前仍需先看 `git status` 和相关 diff,不要重置来源不明的改动 - 梯形图并联短分支的视觉补线已统一为逐格可点击目标,可直接在任意可见补线格插入条件;空补线仍只属于 UI 投影,只有实际使用的间隔才写入 `Wire(span)` - 控制逻辑允许以 `rungs=[]` 启动和保存,不再预置“网络 1”;第一次添加条件、横线或输出时由编辑服务原子创建网络,删除最后一个网络后也能回到空逻辑 - 梯形图空网格只作为编辑位置,不绘制深色真实横线;只有模型中的 `Node / Wire` 和输出连接才绘制导线。连续追加单格横线满十列后,下一次追加自动进入新网络并可一次撤销 - 并联表达式中较短支路会由 UI 派生右侧汇合连接线,不向工程模型写入隐式 `Wire`,保证每条支路视觉上都接到右侧汇合点 - HMI 页面宽高已支持编辑态页面属性设置;业务范围统一为宽 `320~1600`、高 `200~800`,默认新建页面为 `800×400`,页面缩小导致控件越界时由服务层原子拒绝 - HMI 控件属性面板的显示文本输入统一限制为 12 个字符;领域层工程文件文本上限仍为 4096 个 UTF-8 字节 - `docs/二次开发/` 是已有未跟踪资料,不能因当前任务删除 - 测试体系已建立统一 `app/tests/tests.pro` 聚合入口、分层 `.pri` 清单、公共 `TestSupport` fixture 和独立 `performance_tests` 目标;长期测试规则见 `docs/测试约定.md` - 当前没有代码阻塞;实际设备 RUN 联动和离线演示均已完成,下一步是最终交付资料整理 ## 已实现能力 - 工程格式为严格的 `1.0`,保存多 HMI 页面、初始页、报警定义、M/D 注释、多控制逻辑和结构化梯形图;不读取旧 `dataPoints` 或 `stages/branches` 格式 - HMI 现有 8 类控件:Button、Indicator、NumericDisplay、NumericInput、Label、PageJump、AlarmList、ProgressBar - HMI 控件支持静态文字外观:`textColor` 使用 `#RRGGBB`,字体使用 `fontSize`、`fontBold` 和 `fontItalic`;缺失时使用原有默认样式,属性经现有 `properties` 保存,无需升级 JSON 版本 - 字体颜色和基础字体设置在编辑画布和统一运行监控 HMI 中共享同一绘制实现;它们不参与 M/D 绑定、PLC 轮询或离线控制逻辑 - 梯形图使用 `Node / Wire / Series / Parallel` 表达式树和正交网格,不保存自由线段;前 10 列为条件区,输出最多位于第 11 列 - 每个新建或已有网络都投影出 10 个可独立点击的条件网格;空网格横线只属于 UI 插入光标,不写入工程,点击远端空格后才按需保存前置 `Wire(span)` 和真实条件节点 - 已保存的多列 `Wire` 也按单格提供点击目标;在其中一格插入触点时,服务层原子拆分为前置横线、触点和后置横线,继续点击条件工具会逐格消费右侧横线,保持原总列宽以及撤销/重做语义 - 并联分支宽度不足时,渲染层为每个视觉补线格创建带分支 ID 和相对列号的插入目标;服务层按目标分支原子补齐必要横线并插入条件,网络内容区不再误命中整条网络背景 - 梯形图支持 M 触点与上下沿、T/C 触点、普通/置位/复位线圈、TON、CTU/CTD、MOVE、ADD/SUB - 只有输出、没有条件的网络按恒真执行;只有条件、没有输出的启用网络不能运行;空网络扫描时跳过 - 离线执行器按控制逻辑和网络顺序扫描,使用虚拟 M/D,并生成按逻辑 ID 隔离的运行轨迹 - 真机模式只使用 PLC 读回缓存,停止本地逻辑执行器,不下载本地梯形图,也不显示伪造的 PLC 梯形图轨迹 - 自由监控属于当前会话,支持 M/D 批量添加、去重、读取和单点写入,不写入工程 JSON - PLC 通信使用异步 Qt Modbus RTU;轮询地址来自 HMI、报警、梯形图和自由监控的引用并集,写入后等待轮询确认,不乐观修改缓存 - 真机进入要求当前连接完成首次读取;通信故障撤销首读资格并退出真机运行,恢复通信后仍停留在编辑态 - 进入离线或真机运行后,弹出并最大化唯一的工程师运行监控窗口,主编程器保留在后面且布局不变;离线时组合可交互 HMI、软件梯形图轨迹和自由监控,真机时组合可交互 HMI 和自由监控 - 所有数量上限和超限处理见 `docs/用户使用/数量边界确认方案.md`,核心常量集中在 `app/src/domain/project_limits.h` ## 最近完成 - 调整控制逻辑网络生命周期:新建工程和新建逻辑不自动创建网络,首次实际编辑才创建网络 1;首次条件不生成隐式 `Wire`,首次横线只保存一格 `Wire(span=1)`,首次输出生成无条件输出网络;删除最后网络允许恢复为空逻辑 - 收窄梯形图导线投影:空网格和并联补线格不再绘制真实水平线,无输出网络不再绘制条件末端到输出槽的长线;保留网格、选择态和必要的模型导线 - 增加横线连续追加的十列边界处理,普通追加达到十列后自动新建下一网络;自动建网与编辑共用一条撤销记录,串联、并联领域表达式和执行语义保持不变 - 修复短并联支路右端断线:新增支路宽度小于主支路时,渲染层补齐支路输出到右侧汇合点的水平结构连接,保留空网格不落盘和不绘制无逻辑横线的规则 - 统一梯形图可见横线网格交互:新网络空格、持久横线格和并联补线格都可直接点击添加条件;并联远端格会只保存必要的中间 `Wire(span)`,不改变空网络、JSON 或运行语义 - 新增 `LogicEditorService::insertConditionInBranchAtColumn()`,校验目标必须位于直属并联分支的视觉补线范围内,并保持失败回滚、脏标记和一次撤销语义 - 网络背景图元命中范围收窄到标题栏,点击线路内容区不再意外选中整条网络;删除网络仍可通过点击标题栏完成 - 修复梯形图编辑失败回滚后错误保留工程脏标记的问题:回滚同时恢复工程内容和操作前的 `modified_` 状态;保存后超出十列的条件插入不会再触发退出保存提示,已有未保存修改也不会被失败操作清除 - 根据编程器面向设备交付、调试和验证工程师的需求定位,不恢复旧的纯 HMI 操作员窗口;新增职责明确的 `RuntimeMonitorWindow`,承载离线和真机共用的完整运行监控大屏 - 主窗口已移除运行监控页签和运行时布局切换;点击离线或真机运行会弹出最大化监控窗口,右上角返回、关闭弹窗和应用退出分别按统一生命周期处理,且全应用只创建一份 `RuntimeMonitorWidget` - CTU/CTD 输出节点保持现有梯形图网格宽度,将 CV 和 PV 拆成带水平内边距的两行显示,避免 `D4000`、`32767` 等边界配置在右侧电源轨处被裁剪 - 报警列表标题输入上限为 12 个字符,报警文本输入上限为 20 个字符;运行消息保持单行并在空间不足时显示省略号 - 新建报警列表默认尺寸调整为 `360×136`,默认字号比应用字体小 2pt;运行态按当前页 1~5 条记录收缩高度,超过 5 条可通过表头按钮翻页且确认命中使用当前页索引 - 主窗口默认工具栏布局调整为运行模式栏第一行,HMI 或梯形图编辑工具栏第二行;编辑工具栏仍允许用户拖动重新停靠 - 新增 HMI 保留外观属性键和领域校验:颜色为严格 `#RRGGBB`,字号为 `6~72`,粗体和斜体为 `true/false` - HMI 页面属性面板新增宽度和高度编辑;`HmiEditorService::resizePage()` 复用页面边界校验并纳入撤销/重做,成功后画布和工程树尺寸摘要同步刷新;JSON 页面尺寸也统一按 `320~1600 × 200~800` 校验 - 属性面板新增颜色输入与选择按钮、字号、粗体、斜体;通过既有 `HmiEditorService::updateControl()` 原子提交并保留撤销/重做 - `HmiGraphicsItem` 统一应用文字外观,保留地址提示、按钮禁用色、指示灯状态色、控件边框和选中框的原有语义 - 更新工程格式和数量边界文档;新增领域、HMI 编辑服务、JSON 往返和主窗口 UI 测试 - 梯形图编辑器新增按绝对条件列插入和按横线单格替换的服务接口;UI 统一将空格、横线格、已有条件和无选择状态路由到对应编辑用例,选中条件后串联插入会优先替换紧邻的右侧横线格,再考虑扩展网络宽度 - 梯形图条件工具提示已明确支持在选中空网格或横线处插入;线圈等输出指令仍写入独立的固定输出槽 ## 最近验证 - 2026-08-22 网络生命周期和空网格导线调整已通过 `logic_editor_service_tests`、`main_window_tests` 及完整 Release 功能回归(`domain_tests`、`alarm_service_tests`、`hmi_editor_service_tests`、`offline_simulation_service_tests`、`project_management_tests`、`register_monitor_service_tests`、`runtime_mode_service_tests`、`plc_runtime_tests`),Qt Release 主程序在 `build/release-network-lifecycle` 构建并链接成功;本次不涉及 PLC 通信,因此未连接真实 PLC - 2026-08-22 复现并修复短并联支路右端断线:修复前新增图形回归断言失败,修复后 `main_window_tests` 和 `logic_editor_service_tests` Release 均通过;本次只涉及梯形图 UI 投影,不涉及 PLC 通信,因此未连接真实 PLC - 2026-08-22 并联补线网格统一通过独立 Release 构建的 `logic_editor_service_tests` 和 `main_window_tests`;覆盖远端格自动补线、非法列原子拒绝、一次撤销、真实鼠标点击命中网格而非网络背景,以及插入后的剩余可点击横线 - 2026-08-22 Qt Release 主程序已在 `build/release` 重新构建并链接成功;本次改动仅涉及梯形图编辑服务和 UI 投影,不涉及 PLC 通信或真机运行,因此未连接真实 PLC - 2026-08-22 已补齐 `HmiPage::validate()` 的页面最小尺寸校验,领域、编辑服务、JSON 和 UI 统一使用 `320~1600 × 200~800`;重新构建并运行全部 10 个 Release 功能测试目标,均通过 - 2026-08-22 页面领域校验修复后的 Qt Release 主程序已在 `build/release` 重新构建并链接成功;改动不涉及 PLC 通信,因此未连接真实 PLC - 脏标记回滚修复已通过独立 Release 构建的 `logic_editor_service_tests`、`project_management_tests` 和 `main_window_tests`;新增覆盖保存后第 11 个条件插入失败以及已有脏状态下失败操作的回归测试;Qt Release 主程序重新构建成功 - 独立运行监控窗口改动已通过重新生成 qmake 构建后的 `main_window_tests`、`hmi_editor_service_tests`、`offline_simulation_service_tests`、`runtime_mode_service_tests` 和 `plc_runtime_tests`;主窗口测试覆盖最大化弹窗、唯一监控实例、主窗口布局不变、离线与模拟真机 HMI 写入、页面跳转、返回编辑、关闭弹窗、通信故障隐藏、重复进入刷新和应用退出 - 独立运行监控窗口改动后的 Qt Release 主程序已在 `build/runtime-monitor-window-release` 完整构建并链接成功 - 2026-08-20 使用 `COM3 / 9600 / 8E1 / 站号 1` 完成真实 PLC 安全读写:读取 `D4000=0`,临时写入并读回 `1`,随后恢复并读回 `0`;没有下载 PLC 程序,也没有执行切换 RUN 的动作 - 2026-08-21 用户使用 `json/motor_forward_reverse.json` 在已连接的真实 PLC 上完成 RUN 联动手动验收:通过运行监控 HMI 操作正转启动、反转启动和停止,并确认对应运行状态反馈正常;该项验证覆盖实际 PLC 内部程序、接线和现场负载,不由自动化替身测试替代 - 2026-08-21 在 Qt/MinGW 运行库 PATH 正确的独立环境中重新执行 10 个 Release 测试目标,全部通过:`alarm_service_tests`、`domain_tests`、`hmi_editor_service_tests`、`logic_editor_service_tests`、`main_window_tests`、`offline_simulation_service_tests`、`plc_runtime_tests`、`project_management_tests`、`register_monitor_service_tests`、`runtime_mode_service_tests` - 2026-08-21 页面尺寸第一版改动通过 `hmi_editor_service_tests` 和 `main_window_tests`,覆盖原子越界拒绝、撤销/重做、页面属性面板提交和工程树尺寸摘要刷新;随后重新运行全部 10 个 Release 功能测试目标,均通过 - 2026-08-21 页面尺寸最终范围改动新增 JSON 显式边界覆盖:`319/1601` 宽度和 `199/801` 高度加载失败,`320×200` 与 `1600×800` 加载成功;全部 10 个 Release 功能测试目标再次通过 - 2026-08-21 页面尺寸最终范围改动后的 Qt Release 主程序已在 `build/release` 重新构建并链接成功 - 2026-08-21 本地综合演示工程 `json/all_ladder_components_demo.json` 原为 `1280×900`,已调整为 `1280×800`;现有控件仍完整位于页面内,所有本地 JSON 演示工程均符合新页面范围 - 2026-08-21 使用 `scripts/run_qt_tests.ps1 -Configuration Release` 重新构建并运行上述 10 个功能目标及独立 `performance_tests`;功能回归全部通过,性能目标包含 100 个控制逻辑扫描和 4001 个 M 寄存器访问基准 - 2026-08-21 在 `build/tests_aggregate` 对 `app/tests/tests.pro` 执行完整 Release 聚合构建,11 个测试目标(10 个功能目标和 `performance_tests`)全部成功生成可执行文件 - CTU/CTD 显示修复已通过 `main_window_tests`(`QT_QPA_PLATFORM=offscreen`)和 Qt Release 主程序重新构建;改动仅涉及梯形图 UI 投影,因此未连接真实 PLC - 报警列表和分页改动已通过 `domain_tests`、`alarm_service_tests`、`hmi_editor_service_tests`、`project_management_tests` 和 `main_window_tests`;覆盖输入长度、默认五行尺寸、默认字号、运行态高度收缩、六条报警翻页和跨页确认 - HMI 控件属性文本输入上限改动已通过 Qt Release 功能回归和 `main_window_tests`;普通控件与报警列表均确认属性输入框最大长度为 12 - 报警列表改动后的 Qt Release 主程序已重新构建并链接成功;改动不涉及 PLC 通信、Modbus 地址或运行模式,因此未连接真实 PLC - 默认工具栏布局改动已通过 `main_window_tests`(`QT_QPA_PLATFORM=offscreen`)和 Qt Release 主程序重新构建 - 批量删除并联支路回归已通过专项探针、`logic_editor_service_tests` 和 `main_window_tests`;逐个删除、删除完整支路和部分批量删除均保持有效 - 修复后全量测试目标均通过:`alarm_service_tests`、`domain_tests`、`hmi_editor_service_tests`、`logic_editor_service_tests`、`main_window_tests`、`offline_simulation_service_tests`、`plc_runtime_tests`、`project_management_tests`、`register_monitor_service_tests`、`runtime_mode_service_tests` - 本次字体外观改动后的全量测试目标均通过,`main_window_tests` 使用 `QT_QPA_PLATFORM=offscreen` 覆盖了属性面板提交 - Qt Release 主程序已重新构建并链接成功 - `git diff --check` 通过 - 真实 PLC 已使用 `COM3 / 9600 / 8E1 / 站号 1` 验证首次读取、断线恢复和重新首读 - 2026-08-19 已读取 `D4000=0`,写入并读回 `1`,随后恢复并读回 `0`;没有下载 PLC 程序 - 本次修复只影响梯形图编辑结构归一化和删除校验,不涉及 PLC 通信或真机运行,因此没有重复写 PLC - 运行界面此前的双投影生命周期测试已由独立顶层工程师运行监控窗口的唯一投影测试替代,不再构建或保留旧的纯 HMI 操作员窗口 - 本次窗口改动不改变 PLC 通信、Modbus 地址或寄存器读写实现;模拟真机 UI 路径已由假 PLC 仓库覆盖,真实 PLC 安全读写已在同日完成,因此未因窗口承载方式变化重复写设备 - 本次只修改静态 HMI 外观、领域校验和工程持久化,不改变 PLC 通信、Modbus 地址、寄存器读写或运行模式,因此未进行额外真机读写 - 梯形图网格专项覆盖了新网络 10 个点击目标、第五列和第十列插入、前置空档、持久横线首格/中格/末格/单格拆分、满横线连续替换 10 个触点、多网络、满列拒绝、非法配置、原子失败、撤销/重做,以及主窗口真实 `QAction` 点击链路;同时验证普通/置位/复位线圈复用同一固定输出节点,`logic_editor_service_tests` 和 `main_window_tests` 均通过 - 梯形图网格改动后的 `domain_tests`、`project_management_tests`、`offline_simulation_service_tests` 和 `runtime_mode_service_tests` 回归均通过,确认空网格不进入 JSON 或离线执行语义;Qt Release 主程序已在 `build/grid-feature-release` 完整构建并链接成功 - 本次梯形图改动仅涉及编辑服务和 UI 投影,不改变 PLC 通信、真机运行、Modbus 地址或寄存器读写,因此没有重复连接真实 PLC ## 待完成 1. 整理最终演示工程、构建说明和验收记录 2. 根据交付时间评估插件化、新设备适配等可选加分项,不影响当前核心验收闭环 ## 下一会话起点 1. 运行 `git status --short`,确认当前未提交和未跟踪文件仍在 2. 若继续扩展 HMI 外观,优先复用 `HmiAppearanceProperty` 的保留属性键、领域校验和统一绘制路径,避免把样式逻辑放入寄存器或运行服务 3. 若继续扩展梯形图插入交互,保持空网格为 UI 会话投影,只有真实 `Node / Wire / Series / Parallel` 表达式进入工程;条件区继续统一使用 `ProjectLimits::kMaximumConditionColumns` 4. 修改代码后运行受影响测试和 Release 构建;涉及真机通信时按 `AGENTS.md` 做 COM3 读写及恢复验证