From 1e0e7d1973a063af0a6f37fc6dc99a4772242473 Mon Sep 17 00:00:00 2001 From: DXC Date: Tue, 16 Jun 2026 17:53:01 +0800 Subject: [PATCH] =?UTF-8?q?=E7=AB=AF=E5=88=B0=E7=AB=AF=E6=96=B0=E6=9E=B6?= =?UTF-8?q?=E6=9E=84=E9=AA=A8=E6=9E=B6=EF=BC=9Asrc/new=20=E5=8C=85?= =?UTF-8?q?=E5=85=A5=E5=8F=A3=20+=20BaseView=20=E6=8E=A5=E5=8F=A3=E5=A5=91?= =?UTF-8?q?=E7=BA=A6=EF=BC=88dispatch=5Fexecute=20=E6=B2=BF=E7=88=B6?= =?UTF-8?q?=E9=93=BE=E4=B8=8A=E6=BA=AF=20run=5Fsingle=5Fstep=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/new/__init__.py | 19 ++++++++++ src/new/core/__init__.py | 5 +++ src/new/core/base_view.py | 77 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+) create mode 100644 src/new/__init__.py create mode 100644 src/new/core/__init__.py create mode 100644 src/new/core/base_view.py diff --git a/src/new/__init__.py b/src/new/__init__.py new file mode 100644 index 0000000..4edbedf --- /dev/null +++ b/src/new/__init__.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +""" +WQ_GUI 端到端模块化新架构 +============================ + +四层一对一分离: + +* ``core/`` 基础通讯接口(BaseView 等契约) +* ``views/`` 前端皮囊 —— 仅 PyQt UI,零业务 +* ``services/`` 后端大脑 —— 纯函数计算,零 PyQt +* ``main_router.py`` 路由与调度壳,连接前端按钮与后端服务 + +调用链: + Step1View._on_run_clicked + → BaseView.dispatch_execute(step_id, config) + → MainRouter.run_single_step(step_id, config) + → TaskWorker 线程调用 services.step1_service.execute_step1(config) + → 返回 dict 结果 → 日志区 +""" \ No newline at end of file diff --git a/src/new/core/__init__.py b/src/new/core/__init__.py new file mode 100644 index 0000000..be66392 --- /dev/null +++ b/src/new/core/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +"""core —— 基础通讯接口包""" +from .base_view import BaseView + +__all__ = ["BaseView"] \ No newline at end of file diff --git a/src/new/core/base_view.py b/src/new/core/base_view.py new file mode 100644 index 0000000..6dbe556 --- /dev/null +++ b/src/new/core/base_view.py @@ -0,0 +1,77 @@ +#!/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})" + ) \ No newline at end of file