控制器与两个对话框共用 CalibrationService.read_identity,解析失败与缺 SN 分开上报; 本轮改动文件统一 LF,SN 必填回归已锁定。 定向 73 项、校准 UI 8 项与 lint 通过;未跑全量门禁。
12 KiB
Studio 主窗口分步重构计划
目的:plan。范围:apps/studio/src/orisys_studio/app_window.py 及其直接调用方。
当前架构由 Studio 架构 维护;本文件是唯一实施进度记录。
目标与约束
主窗口保留组件装配、跨功能信号连接、窗口几何及明确的关闭顺序。 按职责迁移现有实现,不增加产品功能、依赖、线程或全局状态容器。 会话、回放、布局、显示偏好和记录状态继续由现有控制器持有。 显示层只读取状态;录制与标定采样继续消费采集线程的数据,不依赖刷新频率。
启动、停止、暂停、异常处理、信号顺序及懒加载时机均属于行为保持边界。 关闭时保留预览关闭、采集回调解绑、分析取消与等待、采集和录制收尾、3D 释放的顺序。 测试和工具确实使用的旧入口可以暂留,但每一步必须说明保留原因并更新真实调用方。 不提交、不切换分支;保留所有已有修改,不将并行功能开发混入重构。
顺序与验收
每步都先检查调用方及相关测试,完成后更新本计划和架构文档。 任务顺序为 S0 → S1 → S2 → S3 → S4 → S5 → S6;每一步均可独立审查。
S0:基线与计划
- 记录 HEAD、索引和已有修改,建立独立 scratch 证据目录。
- 在改动前运行状态显示与主窗口相关测试。
基线:2026-10-18,orisys-app 的 main,HEAD 433b76e。
源码为 3,181 行;StudioMainWindow 有 212 个方法,含属性访问器。
原架构文档的 2,309 行及“拆分已完成”属于历史状态。
S1:状态显示
- 新建
status_presenter.py,接收显示事实与目标控件,不接收整个窗口。 - 迁移 phase、来源摘要、标定摘要、有效性及录制统计的格式化与显示。
- 保留
_record_stats注入入口,保证已有截图工具和 UI 检查仍有效。
涉及主窗口、新 Presenter 和定向测试。验收:实时视图不显示回放标题;分析结果保持自己的
传感器身份;未知、无标定、部分轴标定仍可区分;录制关闭中不显示完成,丢失计数完整。
验证:状态 Presenter 独立测试、test_ui_smoke、test_replay_wiring 和现有 UI 检查。
S2:界面构建
- 准备
ui/window_ui.py和ui/window_menus.py,先以独立窗口验证。 - 接入
ui/window_ui.py的控件和布局构建,保持控件身份、顺序及 parent。 - 迁移菜单和 QAction 创建;由窗口显式连接功能操作。
- 迁移对应文字与主题更新,保留必要属性兼容入口。
依赖 S1。涉及主窗口、UI 模块及实际调用方;面板构建和菜单构建分两批验收。
验证:test_ui_elements、test_view_layout、test_sensor_switch_window、主题与语言检查。
3D 仍在原时机创建,启动恢复顺序及保存的布局不变。
S3:实时标定交互
- 提取
live_calibration.py的选择保存、解析、确认及提交请求。 - 文件身份和匹配规则复用
CalibrationService;对话框通过窄接口访问。 - 设备确认、记录版本及采样仍走现有记录通道。
依赖 S2。验证:test_live_calibration_dialog、test_calibration_service 及确认事件测试。
导出不等于应用,应用请求不等于设备确认,序列号不匹配的处理不变。
实施结果(2026-10-19,round 3–5):round 5 统一身份解析并锁定 SN 必填回归
(定向 73 passed、校准 UI 8 passed);R1–R4 见交接,未改断言或基线。
S4:分析配置
- 提取
analysis_setup.py的对话框、裸视频工作目录和分析服务构造。 - 迁移按录制目录保存的完整分析选择,保持接受、取消、重算来源及缓存语义。
ReplayController继续负责执行、取消、缓存及结果选择,不吸收配置逻辑。
依赖 S3 的标定选择接口。验证:test_bare_video_analysis、test_analysis_progress、
test_replay_wiring、test_recording_recalibration;保留录制 chain、标定/设备确认、
显式禁用标定、空载窗口及实际参考帧 ID/时间,取消或失败保留上一完整结果。
S5:运行协调与预览
- 先提取
preview_controller.py,负责设备和预览定时器生命周期。 - 再提取
activity_coordinator.py,统一按钮和快捷键的运行、暂停、停止规则。 - worker 操作通过
SessionController;关闭流程继续在窗口显式排列。
依赖 S4。两批分别验证 test_session_controller、test_pause_controls、
test_transport_review 和连接中停止、断开、异常、重复关闭场景。
普通停止保持非阻塞,退出等待资源结束;预览与采集不能争用相机。
S6:显示入口与兼容桥收尾
- 将 2D/3D 的共同交付协调归入现有
FrameView,调用方显式传入显示上下文。 - 更新测试和工具为真实控制器接口,删除已无调用方的窗口转发。
- 核对依赖方向、无循环、线程归属和文档现状;运行完整门禁。
依赖 S5。验证:test_shared_depth_scale、test_scene3d_frame_views、回放定位与
显示设置重绘测试。2D/3D 使用同一帧;实时不覆盖回放;重绘不启动新分析。
结束条件是主窗口只承担约定职责,且所有相关检查通过,不以行数作为唯一标准。
历史验证摘要
以下是旧批次证据,不是当前 HEAD 的复验。详细原计划快照保存在本轮 scratch 的
plan-before.md;原始日志路径若不可用,应注明证据缺失。
| 批次 | 实施与结果 | 原始证据(相对应用仓库) |
|---|---|---|
| S1,2026-10-18 | 状态迁出;前后定向 125 passed,独立 19 passed,最终 Studio 550 passed/19 skipped;首次门禁 Studio 两项失败保留,隔离通过不能解释原因 | .scratch/studio-window-refactor/20261018-200221/;gate-20261018T120931Z/summary.md |
| S2 准备,2026-10-19 | main a0c13c1;只新增模块及测试,主窗口字节不变;13 passed,lint 通过 | .scratch/studio-window-refactor/20261019-094111/final.xml |
| S2 接线,2026-10-19 | main c6c16df;3070→2894 行;10 控件、35 菜单/action 同对象,18 业务回调留窗口;46→49 passed | .scratch/studio-window-refactor/20261019-095028/ |
S2 串行门禁:lint 通过,UI 632 checks/0 failures;shared 461 passed、15 failed、
18 skipped、3 deselected,涉及映射缺失及模型尺寸;Studio 垃圾回收时访问冲突,无 JUnit。
扩展 UI 131 passed/1 failed,为分析停止后的即时状态断言。旧/新窗口隔离均 4 passed;
旧窗口全套对照无进展后中断。不可据此归因。汇总:
.scratch/studio-window-refactor/gate-20261019T015301Z/。
S1 首次 shared 467 passed、18 skipped、3 deselected,UI 632/0;另有关闭后的
asset_rejected 异步回调,S5 须复核。S1/S2 临时反转条件的回归能发现错误,已恢复源码。
均为 Windows/Python 3.10.19/offscreen;未验证真实设备、可见桌面或硬件 GL。
未放宽断言或基线。S2 的非迁移方法 AST 一致是当时证据,后续功能提交不受其约束。
当前交接:S3 返工 round 5 已交付 review
- task_id:
studio-window-refactor;round:5;updated_at:2026-10-19,Asia/Hong_Kong。 - status:review;owner:DeepSeek 执行方(已停止写入);next_agent:GPT/Claude 验收方。
- 本轮依据:
.scratch/studio-window-refactor/rework-r5/rework-plan.md(用户确认的返工计划)。 未放宽 SN 必填、未改并行任务文件、未用全量门禁证明通过;未暂存/提交/推送/切换分支。 - 授权:用户 2026-10-19 转发该返工计划与启动指令,要求按 R1→R2→R4→R3 执行、R4 先交盘点、 完成标 review 交回验收;先前 S3 授权在范围内继续有效。
基准与输入
| 仓库 | 分支与 HEAD | 起始状态/本轮修改 |
|---|---|---|
D:\orisys_ws\orisys-app |
dev;70b4341fd00707a3a7579d6d36ed4b090c2be068 |
索引空;工作区含并行任务未提交修改(shared analysis/acquisition、replay_controller.py、locales 的 field 键、finger/sensor.json 3→2)与本轮交付;本轮改动见下 |
D:\orisys_ws |
master;9201914cbe335b6862058212af0bc2614f2b4792 |
场加权计划等无关修改;本轮不改根仓库 |
工作目录为应用仓库;解释器 .venv-build\Scripts\python.exe(3.10.19、offscreen)。
R1 只改行尾:计划所列 5 文件、自有文档 2 个、本轮另 3 个改动文件。R3 改
calibration_service.py、live_calibration.py、两个对话框与 4 个测试文件;R2/R4 未改生产代码。
文件 SHA256 见 rework-r5/delivery-sha256.json;其中 R1 涉及的 3 个并行任务文件
(locales×2、sensor.json、replay_controller.py)只规范了行尾,其内容改动不属于本轮。
执行结果
| 项 | 结果与证据 |
|---|---|
| R1 行尾 | 10 个本轮文件均 i/lf w/lf;5 个计划文件整文件 diff 由 3312/3215 降至 103/6,与 --ignore-space-at-eol 一致;转换前后对照 diff 194 行逐行相同。证据 rework-r5/r1-eol.md |
| R2 回归锁定 | 5 类用例齐全(无 SN/无法解析/SN 不一致/未填设备号/非 Finger 文件),resolve() 无“无 SN 放行”返回;遗留 ROLE_DEFAULT 不校验但无 Finger 默认标定、不可达。证据 rework-r5/r2-sn-required.md |
| R4 SN 盘点 | 只读:随包仅 box force_calibration.json(无 SN,规则只对 Finger);Finger 目录与设计导出目录无标定文件;data/dd02-gl 两个 Finger v3 文件带 sn=dd02-gl 且严格解析成功。无 Finger 文件会被拒绝、无需补 SN。证据 rework-r5/sn-inventory.md |
| R3 统一身份解析 | 对照架构文档:UI→无 Qt 服务层是向下依赖、无环(cal_panel 已有同类依赖),方向合规。CalibrationService.read_identity 一次解析返回 (identity, error),identity_of 变薄封装;控制器删除二次 SDK 解析与 ? 兜底;两对话框改走同一判断;对话框错误文案与控制器一致。 |
| R3 测试 | 控制器+服务+对话框+locale 48 passed;定向回归 73 passed;test_ui_smoke -k calibration 8 passed;本轮文件 lint exit 0、无 findings。证据 rework-r5/r3-identity.md、r5-final-20261019-191500/ |
| 文档检查 | doc_lint exit 0、无新增 findings;doc_count 计划 2502/3000、架构 3196/3232。证据 scratch doc-lint.log、doc-count.log |
| 未执行 | 全量门禁(按要求不跑;上轮 studio 57% 原生挂起未解决);未验证真实设备、可见桌面或硬件 GL。 |
历史轮次证据:round 3 门禁 gate-20261019T093016Z/、round 4 返工 handoff-20261019-174000/rework-P2.md;
详细过程在 scratch,不在本表复制。
验收与下一步
- 轮次摘要:1)S0–S2;2)准备 S3 交接;3)S3 实施;4)返工 P2;5)行尾、SN 锁定、盘点与身份解析统一(本轮)。
- 验收者、时间、决定:轮 3 已独立复跑并返工 P2;轮 4 交付后由用户给出本轮返工计划;本轮待复核。
- 下一步:GPT/Claude 复核 R1–R4 证据并独立复跑 R3 测试与行尾检查,决定 done/rework。
S4–S6 仍未实施。改动保持未暂存;提交建议见
.scratch/studio-window-refactor/commit-message.txt, 不含并行任务文件与既有finger/sensor.json。 - scratch:证据保留在
.scratch/studio-window-refactor/;任务.active检查后移除,日志不清理。