# Studio 主窗口分步重构计划 目的:plan。范围:`apps/studio/src/orisys_studio/app_window.py` 及其直接调用方。 当前架构由 [Studio 架构](studio-architecture.md) 维护;本文件是唯一实施进度记录。 ## 目标与约束 主窗口保留组件装配、跨功能信号连接、窗口几何及明确的关闭顺序。 按职责迁移现有实现,不增加产品功能、依赖、线程或全局状态容器。 会话、回放、布局、显示偏好和记录状态继续由现有控制器持有。 显示层只读取状态;录制与标定采样继续消费采集线程的数据,不依赖刷新频率。 启动、停止、暂停、异常处理、信号顺序及懒加载时机均属于行为保持边界。 关闭时保留预览关闭、采集回调解绑、分析取消与等待、采集和录制收尾、3D 释放的顺序。 测试和工具确实使用的旧入口可以暂留,但每一步必须说明保留原因并更新真实调用方。 不提交、不切换分支;保留所有已有修改,不将并行功能开发混入重构。 ## 顺序与验收 每步都先检查调用方及相关测试,完成后更新本计划和架构文档。 任务顺序为 S0 → S1 → S2 → S3 → S4 → S5 → S6;每一步均可独立审查。 ### S0:基线与计划 - [x] 记录 HEAD、索引和已有修改,建立独立 scratch 证据目录。 - [x] 在改动前运行状态显示与主窗口相关测试。 基线:2026-10-18,`orisys-app` 的 `main`,HEAD `433b76e`。 源码为 3,181 行;`StudioMainWindow` 有 212 个方法,含属性访问器。 原架构文档的 2,309 行及“拆分已完成”属于历史状态。 ### S1:状态显示 - [x] 新建 `status_presenter.py`,接收显示事实与目标控件,不接收整个窗口。 - [x] 迁移 phase、来源摘要、标定摘要、有效性及录制统计的格式化与显示。 - [x] 保留 `_record_stats` 注入入口,保证已有截图工具和 UI 检查仍有效。 涉及主窗口、新 Presenter 和定向测试。验收:实时视图不显示回放标题;分析结果保持自己的 传感器身份;未知、无标定、部分轴标定仍可区分;录制关闭中不显示完成,丢失计数完整。 验证:状态 Presenter 独立测试、`test_ui_smoke`、`test_replay_wiring` 和现有 UI 检查。 ### S2:界面构建 - [x] 准备 `ui/window_ui.py` 和 `ui/window_menus.py`,先以独立窗口验证。 - [x] 接入 `ui/window_ui.py` 的控件和布局构建,保持控件身份、顺序及 parent。 - [x] 迁移菜单和 QAction 创建;由窗口显式连接功能操作。 - [x] 迁移对应文字与主题更新,保留必要属性兼容入口。 依赖 S1。涉及主窗口、UI 模块及实际调用方;面板构建和菜单构建分两批验收。 验证:`test_ui_elements`、`test_view_layout`、`test_sensor_switch_window`、主题与语言检查。 3D 仍在原时机创建,启动恢复顺序及保存的布局不变。 ### S3:实时标定交互 - [x] 提取 `live_calibration.py` 的选择保存、解析、确认及提交请求。 - [x] 文件身份和匹配规则复用 `CalibrationService`;对话框通过窄接口访问。 - [x] 设备确认、记录版本及采样仍走现有记录通道。 依赖 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` 检查后移除,日志不清理。