77 lines
3.0 KiB
Python
77 lines
3.0 KiB
Python
#!/usr/bin/env python
|
||
# -*- coding: utf-8 -*-
|
||
"""
|
||
BaseView —— 模块化新页面的标准接口基类
|
||
|
||
设计目标:
|
||
1. 继承自 QWidget,保留 PyQt 控件的全部能力。
|
||
2. 剥离对全局 main_window 的直接依赖——所有跨层通讯通过
|
||
``dispatch_execute`` 沿 ``self.parent()`` 父链向上查找具备
|
||
``run_single_step`` 方法的祖先容器完成。
|
||
3. 声明一组可重写的生命周期空方法(init_ui / get_config /
|
||
set_config / update_work_directory / update_from_config),
|
||
子类按需覆盖,避免基类强制绑定具体 UI 形态。
|
||
"""
|
||
|
||
from PyQt5.QtWidgets import QWidget
|
||
|
||
|
||
class BaseView(QWidget):
|
||
"""所有新页面的标准基类"""
|
||
|
||
def __init__(self, parent=None):
|
||
super().__init__(parent)
|
||
# 全局推送状态的本地缓存——主窗口通过 update_from_config 写入
|
||
self.work_dir = None
|
||
self.pipeline = None
|
||
# 子类应重写 init_ui 以构建自身 UI
|
||
self.init_ui()
|
||
|
||
# ------------------------------------------------------------------
|
||
# 生命周期空方法(子类按需重写)
|
||
# ------------------------------------------------------------------
|
||
def init_ui(self):
|
||
"""构建 UI——子类必须重写"""
|
||
pass
|
||
|
||
def get_config(self) -> dict:
|
||
"""返回当前步骤的配置字典——子类重写"""
|
||
return {}
|
||
|
||
def set_config(self, config: dict):
|
||
"""根据 config 恢复 UI 状态——子类重写"""
|
||
pass
|
||
|
||
def update_work_directory(self, work_dir: str):
|
||
"""主窗口推送工作目录变更——子类按需重写以联动自动填充"""
|
||
self.work_dir = work_dir
|
||
|
||
def update_from_config(self, work_dir: str, pipeline=None):
|
||
"""主窗口推送全局状态——子类可重写以联动 pipeline 状态"""
|
||
self.work_dir = work_dir
|
||
self.pipeline = pipeline
|
||
|
||
# ------------------------------------------------------------------
|
||
# 核心通讯:沿父链向上查找 run_single_step 容器
|
||
# ------------------------------------------------------------------
|
||
def dispatch_execute(self, step_id: str, config: dict):
|
||
"""
|
||
向主窗口请求执行某个步骤。
|
||
|
||
实现要点:
|
||
- 沿 ``self.parent()`` 一路向上爬,直到找到具备
|
||
``run_single_step`` 方法的祖先容器。
|
||
- 找不到则抛出 ``RuntimeError``,便于在迁移早期定位未挂载的面板。
|
||
"""
|
||
ancestor = self.parent()
|
||
while ancestor is not None and not hasattr(ancestor, "run_single_step"):
|
||
ancestor = ancestor.parent()
|
||
|
||
if ancestor is not None and hasattr(ancestor, "run_single_step"):
|
||
ancestor.run_single_step(step_id, config)
|
||
else:
|
||
raise RuntimeError(
|
||
"[BaseView] dispatch_execute 失败:未在父链中找到 "
|
||
"具备 run_single_step 方法的主窗口容器 "
|
||
f"(step_id={step_id})"
|
||
) |