路由壳升级:TaskWorker 三信号 + main_router→main_view 迁移(54/54 smoke 通过)
This commit is contained in:
@ -16,7 +16,7 @@ src/new/
|
|||||||
│ ├── __init__.py
|
│ ├── __init__.py
|
||||||
│ ├── step1_view.py # Step 1 真实视图(继承 BaseView)
|
│ ├── step1_view.py # Step 1 真实视图(继承 BaseView)
|
||||||
│ └── placeholder_view.py # step2-step13 占位视图
|
│ └── placeholder_view.py # step2-step13 占位视图
|
||||||
└── main_router.py # 路由与调度壳(QMainWindow + QThread)
|
└── main_view.py # 路由与调度壳(QMainWindow + QThread)
|
||||||
```
|
```
|
||||||
|
|
||||||
## 端到端调用链
|
## 端到端调用链
|
||||||
@ -28,13 +28,13 @@ Step1View._on_run_clicked (绿色按钮)
|
|||||||
BaseView.dispatch_execute (沿父链上溯)
|
BaseView.dispatch_execute (沿父链上溯)
|
||||||
│ ancestor.run_single_step(step_id, config)
|
│ ancestor.run_single_step(step_id, config)
|
||||||
▼
|
▼
|
||||||
MainRouter.run_single_step (查 ROUTES 表 → 注入 work_dir)
|
MainView.run_single_step (查 ROUTES 表 → 注入 work_dir)
|
||||||
│ TaskWorker(service_func, config).start()
|
│ TaskWorker(service_func, config).start()
|
||||||
▼
|
▼
|
||||||
services.step1_service.execute_step1(config)
|
services.step1_service.execute_step1(config)
|
||||||
│ 调 WaterMaskStep.run(...) → 包装成 dict 返回
|
│ 调 WaterMaskStep.run(...) → 包装成 dict 返回
|
||||||
▼
|
▼
|
||||||
MainRouter._on_step_done (按 status 写日志)
|
MainView._on_step_done (按 status 写日志)
|
||||||
```
|
```
|
||||||
|
|
||||||
## 运行验证
|
## 运行验证
|
||||||
@ -52,13 +52,13 @@ python _smoke_new_arch.py
|
|||||||
|
|
||||||
```cmd
|
```cmd
|
||||||
cd D:\111\office\ZHLduijie\1.WQ\WQ_GUI
|
cd D:\111\office\ZHLduijie\1.WQ\WQ_GUI
|
||||||
python -m src.new.main_router
|
python -m src.new.main_view
|
||||||
```
|
```
|
||||||
|
|
||||||
或:
|
或:
|
||||||
|
|
||||||
```cmd
|
```cmd
|
||||||
python src\new\main_router.py
|
python src\new\main_view.py
|
||||||
```
|
```
|
||||||
|
|
||||||
启动后:
|
启动后:
|
||||||
|
|||||||
@ -3,8 +3,8 @@
|
|||||||
三层冒烟:端到端模块化新架构(src/new/)
|
三层冒烟:端到端模块化新架构(src/new/)
|
||||||
|
|
||||||
Layer 1 service 单元:execute_step1 在各种错误路径返回正确 dict
|
Layer 1 service 单元:execute_step1 在各种错误路径返回正确 dict
|
||||||
Layer 2 view offscreen:Step1View UI 行为符合契约(不依赖 main_router)
|
Layer 2 view offscreen:Step1View UI 行为符合契约(不依赖 main_view)
|
||||||
Layer 3 end-to-end:MainRouter 创建 → 切到 step1 → 点击 → 日志验证
|
Layer 3 end-to-end:MainView 创建 → 切到 step1 → 点击 → 日志验证
|
||||||
|
|
||||||
运行方式(项目根)::
|
运行方式(项目根)::
|
||||||
|
|
||||||
@ -247,17 +247,17 @@ def smoke_view():
|
|||||||
# =========================================================================
|
# =========================================================================
|
||||||
def smoke_e2e():
|
def smoke_e2e():
|
||||||
print("\n" + "=" * 70)
|
print("\n" + "=" * 70)
|
||||||
print("Layer 3 —— end-to-end(MainRouter 路由 + TaskWorker 调度)")
|
print("Layer 3 —— end-to-end(MainView 路由 + TaskWorker 调度)")
|
||||||
print("=" * 70)
|
print("=" * 70)
|
||||||
|
|
||||||
from PyQt5.QtCore import QEventLoop, QTimer
|
from PyQt5.QtCore import QEventLoop, QTimer
|
||||||
from PyQt5.QtWidgets import QApplication
|
from PyQt5.QtWidgets import QApplication
|
||||||
app = QApplication.instance() or QApplication(sys.argv)
|
app = QApplication.instance() or QApplication(sys.argv)
|
||||||
|
|
||||||
from src.new.main_router import MainRouter, ROUTES
|
from src.new.main_view import MainView, ROUTES
|
||||||
|
|
||||||
win = MainRouter()
|
win = MainView()
|
||||||
report("L3", "MainRouter 实例化成功", win is not None)
|
report("L3", "MainView 实例化成功", win is not None)
|
||||||
report("L3", "ROUTES 共 13 条", len(ROUTES) == 13, f"实际={len(ROUTES)}")
|
report("L3", "ROUTES 共 13 条", len(ROUTES) == 13, f"实际={len(ROUTES)}")
|
||||||
report("L3", "nav_list 项数 == 13", win.nav_list.count() == 13,
|
report("L3", "nav_list 项数 == 13", win.nav_list.count() == 13,
|
||||||
f"count={win.nav_list.count()}")
|
f"count={win.nav_list.count()}")
|
||||||
|
|||||||
@ -8,12 +8,12 @@ WQ_GUI 端到端模块化新架构
|
|||||||
* ``core/`` 基础通讯接口(BaseView 等契约)
|
* ``core/`` 基础通讯接口(BaseView 等契约)
|
||||||
* ``views/`` 前端皮囊 —— 仅 PyQt UI,零业务
|
* ``views/`` 前端皮囊 —— 仅 PyQt UI,零业务
|
||||||
* ``services/`` 后端大脑 —— 纯函数计算,零 PyQt
|
* ``services/`` 后端大脑 —— 纯函数计算,零 PyQt
|
||||||
* ``main_router.py`` 路由与调度壳,连接前端按钮与后端服务
|
* ``main_view.py`` 路由与调度壳,连接前端按钮与后端服务
|
||||||
|
|
||||||
调用链:
|
调用链:
|
||||||
Step1View._on_run_clicked
|
Step1View._on_run_clicked
|
||||||
→ BaseView.dispatch_execute(step_id, config)
|
→ BaseView.dispatch_execute(step_id, config)
|
||||||
→ MainRouter.run_single_step(step_id, config)
|
→ MainView.run_single_step(step_id, config)
|
||||||
→ TaskWorker 线程调用 services.step1_service.execute_step1(config)
|
→ TaskWorker 线程调用 services.step1_service.execute_step1(config)
|
||||||
→ 返回 dict 结果 → 日志区
|
→ 返回 dict 结果 → 日志区
|
||||||
"""
|
"""
|
||||||
@ -1,35 +1,40 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
MainRouter —— 端到端模块化新架构的路由与调度壳
|
MainView —— 端到端模块化新架构的路由与调度壳(主窗口)
|
||||||
=================================================
|
=========================================================
|
||||||
|
|
||||||
职责
|
职责
|
||||||
----
|
----
|
||||||
1. **路由**:根据 ``ROUTES`` 表动态加载每个 step 的 view(前端皮囊)
|
1. **路由**:根据 ``ROUTES`` 表动态加载每个 step 的 view(前端皮囊)
|
||||||
和 service(后端大脑),左侧 ``QListWidget`` 导航,右侧
|
和 service(后端大脑),左侧 ``QListWidget`` 导航,右侧
|
||||||
``QStackedWidget`` 承载 view。
|
``QStackedWidget`` 承载 view。
|
||||||
2. **解耦通讯**:view 不直接持有 main_router 引用;按钮点击通过
|
2. **解耦通讯**:view 不直接持有 main_view 引用;按钮点击通过
|
||||||
``BaseView.dispatch_execute`` 沿父链回到本类 ``run_single_step``。
|
``BaseView.dispatch_execute`` 沿父链回到本类 ``run_single_step``。
|
||||||
3. **后台执行**:内置 ``TaskWorker(QThread)``,把 service 调用丢进
|
3. **后台执行**:内置 ``TaskWorker(QThread)``(三信号协议:
|
||||||
子线程,避免阻塞 UI。
|
``log_msg / finished / error``),把 service 调用丢进子线程,
|
||||||
|
避免阻塞 UI。
|
||||||
4. **日志** :底部 ``QTextEdit`` 集中输出路由与 service 结果。
|
4. **日志** :底部 ``QTextEdit`` 集中输出路由与 service 结果。
|
||||||
|
|
||||||
|
本文件由原 ``src/new/main_router.py`` 迁移而来,类名 ``MainRouter`` 改名为
|
||||||
|
``MainView`` 以贴合"视图壳"语义,同时按用户原意把 ``TaskWorker`` 从单信号
|
||||||
|
(``finished_with_result``)升级为三信号协议。
|
||||||
|
|
||||||
运行方式
|
运行方式
|
||||||
--------
|
--------
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
# 方式 A:作为模块运行(推荐)
|
# 方式 A:作为模块运行(推荐)
|
||||||
cd D:/111/office/ZHLduijie/1.WQ/WQ_GUI
|
cd D:/111/office/ZHLduijie/1.WQ/WQ_GUI
|
||||||
python -m src.new.main_router
|
python -m src.new.main_view
|
||||||
|
|
||||||
# 方式 B:直接脚本运行
|
# 方式 B:直接脚本运行
|
||||||
python src/new/main_router.py
|
python src/new/main_view.py
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import importlib
|
import importlib
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import traceback
|
import traceback
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@ -41,7 +46,7 @@ from PyQt5.QtWidgets import (
|
|||||||
QWidget,
|
QWidget,
|
||||||
)
|
)
|
||||||
|
|
||||||
# 让 ``python src/new/main_router.py`` 直接运行时也能 import ``src.xxx``
|
# 让 ``python src/new/main_view.py`` 直接运行时也能 import ``src.xxx``
|
||||||
_HERE = Path(__file__).resolve().parent # .../src/new
|
_HERE = Path(__file__).resolve().parent # .../src/new
|
||||||
_SRC_ROOT = _HERE.parent # .../src
|
_SRC_ROOT = _HERE.parent # .../src
|
||||||
if str(_SRC_ROOT) not in sys.path:
|
if str(_SRC_ROOT) not in sys.path:
|
||||||
@ -80,15 +85,27 @@ ROUTES = [
|
|||||||
|
|
||||||
|
|
||||||
# =========================================================================
|
# =========================================================================
|
||||||
# TaskWorker:QThread 后台执行器
|
# TaskWorker:QThread 后台执行器(三信号协议)
|
||||||
# =========================================================================
|
# =========================================================================
|
||||||
class TaskWorker(QThread):
|
class TaskWorker(QThread):
|
||||||
"""后台执行 ``service_func(config)`` 并把结果 emit 回主线程
|
"""后台执行 ``service_func(config)`` 并通过三信号协议回报主线程
|
||||||
|
|
||||||
|
信号协议
|
||||||
|
--------
|
||||||
|
* ``log_msg(str)`` —— 启动 / 完成 / 异常等关键节点的人类可读日志
|
||||||
|
* ``finished(dict)`` —— service 正常返回(含 service 内部 try/except
|
||||||
|
转成的 error 状态 dict)
|
||||||
|
* ``error(str)`` —— worker 自身捕获的未预期异常(含 traceback),
|
||||||
|
与 finished 中的 status='error' 语义不同:error 表示 worker
|
||||||
|
完全崩溃,无法产出任何结果 dict。
|
||||||
|
|
||||||
为什么用 QThread 而不是 Thread:service_func 可能涉及 rasterio /
|
为什么用 QThread 而不是 Thread:service_func 可能涉及 rasterio /
|
||||||
matplotlib 等原生扩展,主线程与子线程的 Qt 事件循环隔离更稳。
|
matplotlib 等原生扩展,主线程与子线程的 Qt 事件循环隔离更稳。
|
||||||
"""
|
"""
|
||||||
finished_with_result = pyqtSignal(dict)
|
|
||||||
|
log_msg = pyqtSignal(str)
|
||||||
|
finished = pyqtSignal(dict)
|
||||||
|
error = pyqtSignal(str)
|
||||||
|
|
||||||
def __init__(self, service_func, config: dict):
|
def __init__(self, service_func, config: dict):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
@ -96,22 +113,25 @@ class TaskWorker(QThread):
|
|||||||
self.config = config
|
self.config = config
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
|
func_name = getattr(self.service_func, "__name__", "<anonymous>")
|
||||||
|
self.log_msg.emit(f"[Worker] 启动 {func_name}")
|
||||||
try:
|
try:
|
||||||
result = self.service_func(self.config)
|
result = self.service_func(self.config)
|
||||||
except Exception as e: # noqa: BLE001
|
except Exception as e: # noqa: BLE001 —— worker 兜底捕获所有未预期异常
|
||||||
result = {
|
tb = traceback.format_exc()
|
||||||
"status": "error",
|
self.log_msg.emit(f"[Worker] 异常 {type(e).__name__}: {e}")
|
||||||
"output_path": None,
|
self.error.emit(f"{type(e).__name__}: {e}\n{tb}")
|
||||||
"message": f"{type(e).__name__}: {e}",
|
return
|
||||||
"traceback": traceback.format_exc(),
|
|
||||||
}
|
status = result.get("status", "unknown") if isinstance(result, dict) else "unknown"
|
||||||
self.finished_with_result.emit(result)
|
self.log_msg.emit(f"[Worker] 完成,status={status}")
|
||||||
|
self.finished.emit(result)
|
||||||
|
|
||||||
|
|
||||||
# =========================================================================
|
# =========================================================================
|
||||||
# MainRouter:QMainWindow 路由壳
|
# MainView:QMainWindow 路由壳
|
||||||
# =========================================================================
|
# =========================================================================
|
||||||
class MainRouter(QMainWindow):
|
class MainView(QMainWindow):
|
||||||
"""新架构的轻量路由主窗口"""
|
"""新架构的轻量路由主窗口"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -128,7 +148,7 @@ class MainRouter(QMainWindow):
|
|||||||
self._build_ui()
|
self._build_ui()
|
||||||
self._build_routes()
|
self._build_routes()
|
||||||
|
|
||||||
self._log("[Boot] MainRouter 初始化完成")
|
self._log("[Boot] MainView 初始化完成")
|
||||||
self._log(f"[Boot] 已注册 {len(ROUTES)} 条路由(step1 真实 / step2-step13 占位)")
|
self._log(f"[Boot] 已注册 {len(ROUTES)} 条路由(step1 真实 / step2-step13 占位)")
|
||||||
|
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
@ -249,14 +269,15 @@ class MainRouter(QMainWindow):
|
|||||||
1. 查路由表;
|
1. 查路由表;
|
||||||
2. 注入 ``work_dir``(避免 view 重复感知);
|
2. 注入 ``work_dir``(避免 view 重复感知);
|
||||||
3. 启动 ``TaskWorker`` 在子线程运行 service;
|
3. 启动 ``TaskWorker`` 在子线程运行 service;
|
||||||
4. 完成后 emit 回主线程并写日志。
|
4. 三信号路由:log_msg → 日志框;finished → 状态分支日志;
|
||||||
|
error → 未预期异常写日志 + traceback。
|
||||||
"""
|
"""
|
||||||
route = self._route_map.get(step_id)
|
route = self._route_map.get(step_id)
|
||||||
if route is None:
|
if route is None:
|
||||||
self._log(f"[Router] 未知 step_id: {step_id}")
|
self._log(f"[Router] 未知 step_id: {step_id}")
|
||||||
return
|
return
|
||||||
|
|
||||||
# 注入 work_dir(仅当 view 未带且 main_router 已配置时)
|
# 注入 work_dir(仅当 view 未带且 main_view 已配置时)
|
||||||
if self.work_dir and "work_dir" not in config_dict:
|
if self.work_dir and "work_dir" not in config_dict:
|
||||||
config_dict = {**config_dict, "work_dir": self.work_dir}
|
config_dict = {**config_dict, "work_dir": self.work_dir}
|
||||||
|
|
||||||
@ -272,7 +293,9 @@ class MainRouter(QMainWindow):
|
|||||||
return
|
return
|
||||||
|
|
||||||
self.worker = TaskWorker(service_func, config_dict)
|
self.worker = TaskWorker(service_func, config_dict)
|
||||||
self.worker.finished_with_result.connect(self._on_step_done)
|
self.worker.log_msg.connect(self._log)
|
||||||
|
self.worker.finished.connect(self._on_step_done)
|
||||||
|
self.worker.error.connect(self._on_step_error)
|
||||||
self.worker.start()
|
self.worker.start()
|
||||||
|
|
||||||
def _load_callable(self, module_name: str, attr_name: str):
|
def _load_callable(self, module_name: str, attr_name: str):
|
||||||
@ -286,7 +309,11 @@ class MainRouter(QMainWindow):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def _on_step_done(self, result: dict):
|
def _on_step_done(self, result: dict):
|
||||||
"""TaskWorker 完成回调——按 status 分支写日志"""
|
"""TaskWorker finished 回调——按 status 分支写日志
|
||||||
|
|
||||||
|
注:service 内部 try/except 转换的 status='error' 也走这里;
|
||||||
|
这与 error 信号(worker 自身崩溃)语义不同。
|
||||||
|
"""
|
||||||
status = result.get("status", "unknown")
|
status = result.get("status", "unknown")
|
||||||
message = result.get("message", "")
|
message = result.get("message", "")
|
||||||
output_path = result.get("output_path")
|
output_path = result.get("output_path")
|
||||||
@ -298,12 +325,16 @@ class MainRouter(QMainWindow):
|
|||||||
self._log(f"[Service↻] {message}(已复用历史结果)")
|
self._log(f"[Service↻] {message}(已复用历史结果)")
|
||||||
elif status == "not_implemented":
|
elif status == "not_implemented":
|
||||||
self._log(f"[Service…] {message}")
|
self._log(f"[Service…] {message}")
|
||||||
else: # error
|
else: # error(service 内部已转 dict)
|
||||||
self._log(f"[Service✗] {message}(mode={mode or 'n/a'})")
|
self._log(f"[Service✗] {message}(mode={mode or 'n/a'})")
|
||||||
tb = result.get("traceback")
|
tb = result.get("traceback")
|
||||||
if tb:
|
if tb:
|
||||||
self._log(tb)
|
self._log(tb)
|
||||||
|
|
||||||
|
def _on_step_error(self, msg: str):
|
||||||
|
"""TaskWorker error 信号回调——worker 自身捕获的未预期异常"""
|
||||||
|
self._log(f"[Worker✗] 未预期异常:\n{msg}")
|
||||||
|
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
# 日志:所有日志统一走这里
|
# 日志:所有日志统一走这里
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
@ -319,7 +350,7 @@ class MainRouter(QMainWindow):
|
|||||||
def main():
|
def main():
|
||||||
from PyQt5.QtWidgets import QApplication
|
from PyQt5.QtWidgets import QApplication
|
||||||
app = QApplication(sys.argv)
|
app = QApplication(sys.argv)
|
||||||
win = MainRouter()
|
win = MainView()
|
||||||
win.show()
|
win.show()
|
||||||
sys.exit(app.exec_())
|
sys.exit(app.exec_())
|
||||||
|
|
||||||
@ -2,7 +2,7 @@
|
|||||||
"""
|
"""
|
||||||
PlaceholderService —— 通用占位后端(用于尚未迁移的步骤)
|
PlaceholderService —— 通用占位后端(用于尚未迁移的步骤)
|
||||||
|
|
||||||
返回 ``{"status": "not_implemented", ...}``,main_router 据此在日志区
|
返回 ``{"status": "not_implemented", ...}``,main_view 据此在日志区
|
||||||
输出友好提示;不抛异常、不阻塞 UI 线程。
|
输出友好提示;不抛异常、不阻塞 UI 线程。
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -15,7 +15,7 @@ def execute_placeholder(config: Dict[str, Any]) -> Dict[str, Any]:
|
|||||||
"""通用占位执行函数
|
"""通用占位执行函数
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
config: 由 view.get_config() 序列化、再经 main_router 注入 work_dir 的字典
|
config: 由 view.get_config() 序列化、再经 main_view 注入 work_dir 的字典
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
标准结果字典 ``{status, output_path, message}``,其中 status="not_implemented"
|
标准结果字典 ``{status, output_path, message}``,其中 status="not_implemented"
|
||||||
|
|||||||
@ -3,14 +3,14 @@
|
|||||||
Step1 后端计算服务(水域掩膜生成)
|
Step1 后端计算服务(水域掩膜生成)
|
||||||
=====================================
|
=====================================
|
||||||
|
|
||||||
这是一个**纯计算函数**——绝对不引用 PyQt、绝对不引用 main_router、
|
这是一个**纯计算函数**——绝对不引用 PyQt、绝对不引用 main_view、
|
||||||
绝对不读写全局变量。它只:
|
绝对不读写全局变量。它只:
|
||||||
|
|
||||||
1. 从 ``config`` 字典读取参数;
|
1. 从 ``config`` 字典读取参数;
|
||||||
2. 调用旧版 ``WaterMaskStep.run`` 执行水域掩膜生成;
|
2. 调用旧版 ``WaterMaskStep.run`` 执行水域掩膜生成;
|
||||||
3. 返回结果字典 ``{status, output_path, message}``。
|
3. 返回结果字典 ``{status, output_path, message}``。
|
||||||
|
|
||||||
调用入口(由 main_router 在后台 QThread 中调用):
|
调用入口(由 main_view 在后台 QThread 中调用):
|
||||||
|
|
||||||
execute_step1({
|
execute_step1({
|
||||||
"mask_path": "D:/xx.shp", # 现有掩膜路径(NDWI 模式下可为 None)
|
"mask_path": "D:/xx.shp", # 现有掩膜路径(NDWI 模式下可为 None)
|
||||||
@ -18,7 +18,7 @@ Step1 后端计算服务(水域掩膜生成)
|
|||||||
"ndwi_threshold": 0.4, # NDWI 阈值
|
"ndwi_threshold": 0.4, # NDWI 阈值
|
||||||
"img_path": "D:/ref.dat", # 参考影像
|
"img_path": "D:/ref.dat", # 参考影像
|
||||||
"output_path": "D:/mask.dat", # NDWI 输出路径(可选)
|
"output_path": "D:/mask.dat", # NDWI 输出路径(可选)
|
||||||
"work_dir": "D:/workspace", # 工作目录(main_router 注入)
|
"work_dir": "D:/workspace", # 工作目录(main_view 注入)
|
||||||
})
|
})
|
||||||
|
|
||||||
返回字典字段:
|
返回字典字段:
|
||||||
@ -56,7 +56,7 @@ def execute_step1(config: Dict[str, Any]) -> Dict[str, Any]:
|
|||||||
"""Step 1 后端计算入口——纯函数
|
"""Step 1 后端计算入口——纯函数
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
config: 由前端 view.get_config() 序列化、再经 main_router 注入 work_dir 的字典
|
config: 由前端 view.get_config() 序列化、再经 main_view 注入 work_dir 的字典
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
标准结果字典 ``{status, output_path, message, mode}``
|
标准结果字典 ``{status, output_path, message, mode}``
|
||||||
@ -87,7 +87,7 @@ def execute_step1(config: Dict[str, Any]) -> Dict[str, Any]:
|
|||||||
generate_png=True,
|
generate_png=True,
|
||||||
output_path=output_path,
|
output_path=output_path,
|
||||||
water_mask_dir=water_mask_dir,
|
water_mask_dir=water_mask_dir,
|
||||||
callback=None, # 日志由 main_router 统一接管
|
callback=None, # 日志由 main_view 统一接管
|
||||||
)
|
)
|
||||||
except FileNotFoundError as e:
|
except FileNotFoundError as e:
|
||||||
return {
|
return {
|
||||||
|
|||||||
@ -5,7 +5,7 @@ PlaceholderView —— 通用占位视图(用于尚未迁移的步骤)
|
|||||||
仅显示 step 名称与"待实现"提示,仍遵循 BaseView 契约:
|
仅显示 step 名称与"待实现"提示,仍遵循 BaseView 契约:
|
||||||
|
|
||||||
* ``get_config()`` 返回空 dict(service 端据此走占位分支)
|
* ``get_config()`` 返回空 dict(service 端据此走占位分支)
|
||||||
* 点击"执行"按钮仍会触发 ``dispatch_execute``,便于在 main_router
|
* 点击"执行"按钮仍会触发 ``dispatch_execute``,便于在 main_view
|
||||||
中验证路由链路完整通畅
|
中验证路由链路完整通畅
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ class PlaceholderView(BaseView):
|
|||||||
|
|
||||||
hint = QLabel(
|
hint = QLabel(
|
||||||
"此步骤的 View 与 Service 尚未迁移到端到端模块化新架构。\n"
|
"此步骤的 View 与 Service 尚未迁移到端到端模块化新架构。\n"
|
||||||
"按钮仍可点击以验证 main_router 路由链路完整性。"
|
"按钮仍可点击以验证 main_view 路由链路完整性。"
|
||||||
)
|
)
|
||||||
hint.setAlignment(Qt.AlignCenter)
|
hint.setAlignment(Qt.AlignCenter)
|
||||||
hint.setWordWrap(True)
|
hint.setWordWrap(True)
|
||||||
|
|||||||
@ -17,9 +17,9 @@ Step1View —— Step 1(水域掩膜生成)的前端视图(端到端模块
|
|||||||
|
|
||||||
Step1View._on_run_clicked
|
Step1View._on_run_clicked
|
||||||
→ BaseView.dispatch_execute("step1", config)
|
→ BaseView.dispatch_execute("step1", config)
|
||||||
→ MainRouter.run_single_step(step_id, config)
|
→ MainView.run_single_step(step_id, config)
|
||||||
→ TaskWorker → services.step1_service.execute_step1(config)
|
→ TaskWorker → services.step1_service.execute_step1(config)
|
||||||
→ 返回结果 dict → MainRouter 日志区
|
→ 返回结果 dict → MainView 日志区
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
@ -279,6 +279,6 @@ class Step1View(BaseView):
|
|||||||
|
|
||||||
所有跨层通讯一律走 ``dispatch_execute``:
|
所有跨层通讯一律走 ``dispatch_execute``:
|
||||||
|
|
||||||
Step1View → 沿父链上溯 → MainRouter.run_single_step(step_id, config)
|
Step1View → 沿父链上溯 → MainView.run_single_step(step_id, config)
|
||||||
"""
|
"""
|
||||||
self.dispatch_execute("step1", self.get_config())
|
self.dispatch_execute("step1", self.get_config())
|
||||||
Reference in New Issue
Block a user