feat: 懒加载面板Catch-up状态回放 + 上一步/下一步向导导航按钮
This commit is contained in:
@ -20,6 +20,7 @@ from PyQt5.QtCore import Qt
|
||||
|
||||
from src.gui.core.panel_registry import PANEL_REGISTRY
|
||||
from src.gui.core.dependency_subscriber import subscribe_panel_to_dependencies
|
||||
from src.gui.core.event_bus import global_event_bus
|
||||
|
||||
|
||||
class PanelFactory:
|
||||
@ -184,6 +185,90 @@ class PanelFactory:
|
||||
if deps:
|
||||
subscribe_panel_to_dependencies(panel, step_id, deps)
|
||||
|
||||
# ★ Catch-up:向刚苏醒的懒加载面板回放已累积的状态
|
||||
# (面板在 OutputUpdated 事件广播之后才实例化,错过了事件,
|
||||
# 必须主动回放 step_outputs + 全局输入,否则输入框全空)
|
||||
self._replay_state_to_panel(panel)
|
||||
|
||||
# ── Catch-up 状态追溯 ────────────────────────────────────
|
||||
|
||||
def _replay_state_to_panel(self, panel):
|
||||
"""向刚实例化的懒加载面板回放已累积的状态。
|
||||
|
||||
三步回放:
|
||||
1. update_from_config —— 生成默认输出路径 + 跨面板参数读取
|
||||
2. 回放 WorkspaceManager.step_outputs —— 已运行步骤的产出文件路径
|
||||
3. 实时扫描已加载面板 —— 读取被依赖的属性值(如 Step1 的 img_file)
|
||||
发布为 OutputUpdated,触发 dependency_subscriber 回填输入框
|
||||
"""
|
||||
# 1. update_from_config:生成默认输出路径
|
||||
if hasattr(panel, 'update_from_config'):
|
||||
try:
|
||||
work_dir = self._get_current_work_dir()
|
||||
panel.update_from_config(work_dir=work_dir, pipeline=None)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# 2. 回放 WorkspaceManager 中已累积的 step_outputs
|
||||
ws_manager = self._get_workspace_manager()
|
||||
if ws_manager:
|
||||
for src_step_id, outputs in ws_manager.step_outputs.items():
|
||||
for output_type, path in outputs.items():
|
||||
if not path:
|
||||
continue
|
||||
global_event_bus.publish('OutputUpdated', {
|
||||
'step_id': src_step_id,
|
||||
'output_type': output_type,
|
||||
'path': path,
|
||||
})
|
||||
|
||||
# 3. 实时扫描已加载面板中被依赖的属性(覆盖全局输入如 reference_img)
|
||||
self._replay_live_panel_inputs()
|
||||
|
||||
def _replay_live_panel_inputs(self):
|
||||
"""遍历 PANEL_REGISTRY 依赖声明,从已加载面板实时读取属性值。
|
||||
|
||||
若源面板已实例化,读取其 widget 的当前值并发布为 OutputUpdated,
|
||||
确保懒加载面板能收到全局输入(如 Step1.img_file → reference_img)。
|
||||
"""
|
||||
for entry in self._registry:
|
||||
deps = entry.get('dependencies')
|
||||
if not deps:
|
||||
continue
|
||||
for _input_field, (dep_step, output_type, panel_attr) in deps.items():
|
||||
src_panel = self._panels.get(dep_step)
|
||||
if src_panel is None:
|
||||
continue
|
||||
widget = getattr(src_panel, panel_attr, None)
|
||||
if widget is None:
|
||||
continue
|
||||
path = ''
|
||||
if hasattr(widget, 'get_path'):
|
||||
path = widget.get_path().strip()
|
||||
elif hasattr(widget, 'text'):
|
||||
path = widget.text().strip()
|
||||
if not path:
|
||||
continue
|
||||
global_event_bus.publish('OutputUpdated', {
|
||||
'step_id': dep_step,
|
||||
'output_type': output_type,
|
||||
'path': path,
|
||||
})
|
||||
|
||||
def _get_current_work_dir(self):
|
||||
"""从 WorkspaceInitializer 获取当前工作目录。"""
|
||||
try:
|
||||
return self._main_window._workspace_initializer.work_dir
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
def _get_workspace_manager(self):
|
||||
"""从 WorkspaceInitializer 获取 WorkspaceManager 实例。"""
|
||||
try:
|
||||
return self._main_window._workspace_initializer.workspace_manager
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
def _preload_neighbors(self, index):
|
||||
"""预加载当前 tab 的邻居(根据 preload_window 配置)。"""
|
||||
if self._preload_window < 0:
|
||||
|
||||
Reference in New Issue
Block a user