Files
WQ_GUI/src/new/main_view.py

757 lines
30 KiB
Python
Raw Normal View History

# -*- coding: utf-8 -*-
"""
MainView —— 端到端模块化新架构的路由与调度壳(主窗口)
=========================================================
职责
----
1. **路由**:根据 ``ROUTES`` 表动态加载每个 step 的 view(前端皮囊)
和 service(后端大脑),左侧 ``QListWidget`` 导航,右侧
``QStackedWidget`` 承载 view。
2. **解耦通讯**:view 不直接持有 main_view 引用;按钮点击通过
``BaseView.dispatch_execute`` 沿父链回到本类 ``run_single_step``。
3. **后台执行**:内置 ``TaskWorker(QThread)``(三信号协议:
``log_msg / finished / error``),把 service 调用丢进子线程,
避免阻塞 UI。
4. **日志** :底部 ``QTextEdit`` 集中输出路由与 service 结果。
本文件由原 ``src/new/main_router.py`` 迁移而来,类名 ``MainRouter`` 改名为
``MainView`` 以贴合"视图壳"语义,同时按用户原意把 ``TaskWorker`` 从单信号
(``finished_with_result``)升级为三信号协议。
运行方式
--------
::
# 方式 A:作为模块运行(推荐)
cd D:/111/office/ZHLduijie/1.WQ/WQ_GUI
python -m src.new.main_view
# 方式 B:直接脚本运行
python src/new/main_view.py
"""
from __future__ import annotations
import importlib
feat(new-arch):主窗口全功能增强(图标系统 + 全链路参数同步 + 服务输出统一解析 + Step12 分类浏览) 1. main_view.py:图标系统 + 全链路参数自动传导 - 新增 _res() 解析项目根的相对路径,PyInstaller 打包后兼容 sys._MEIPASS。 - 新增 QListWidgetItem / QMessageBox 导入,左侧导航列表支持右键菜单 + 错误弹窗。 - ROUTES 12 条全部新增 icon 字段("1.png" 等),侧边栏显示业务图标。 - 新增 step_outputs 缓存机制:每个 step 完成后把 output_path 写入 self.step_outputs。 - 新增 _sync_dependencies() 同步函数 + _safe_set_config() 包装器, 按依赖图把上游产物推给下游 view: step1 → step6 water_mask_path step3 → step4 / step6 / step10 deglint_img_path / bsq_path step4 → step9 sampling_csv_path step5 → step6 csv_path step6 → step7 / step8 training_csv_path step8 → step9 models_dir(父目录) step9 → step11 prediction_csv_dir / prediction_csv_path(双推) step10 → step11 geotiff_dir / geotiff_path(双推) 2. services/step1-13:统一输出解析器集成 - 新增 src/new/services/_output_resolver.py,提供 resolve_output_dir / copy_to_user_path / get_user_output_path / is_user_specified 四个共享工具。 - 每个 service 把原有的私有 _resolve_xxx_dir 改为调用 resolve_output_dir, 强制执行"用户优先"规则(用户指定 output_path 时用其父目录,否则用 work_dir/<subdir>)。 - 用户指定文件名 vs 底层硬编码文件名的"事后劫持"通过 copy_to_user_path 完成 (覆盖 step2、step4、step7、step8 等底层 step 不接受 output_path 关键字的步骤)。 3. views/step12_view.py:恢复 ImageCategoryTree + ImageViewerWidget 高级组件 - 删掉精简版占位 Label,挂回旧版的 ImageCategoryTree(按"模型评估/光谱分析/ 统计图表/处理结果/含量分布图"五类自动归类工作目录下的图像文件)。 - 挂回 ImageViewerWidget(滚轮缩放 0.1x-5x + 50ms 防抖 + FastTransformation/ SmoothTransformation 智能切换 + Ctrl+Wheel + 工具栏)。 - 扫描按钮接通 image_tree.scan_directory(),选中节点即时加载到 image_viewer。 - 按钮样式切换为 ModernStylesheet(success/primary)统一视觉。
2026-06-17 13:28:58 +08:00
import os
import sys
import traceback
from pathlib import Path
from PyQt5.QtCore import Qt, QThread, pyqtSignal
feat(new-arch):主窗口全功能增强(图标系统 + 全链路参数同步 + 服务输出统一解析 + Step12 分类浏览) 1. main_view.py:图标系统 + 全链路参数自动传导 - 新增 _res() 解析项目根的相对路径,PyInstaller 打包后兼容 sys._MEIPASS。 - 新增 QListWidgetItem / QMessageBox 导入,左侧导航列表支持右键菜单 + 错误弹窗。 - ROUTES 12 条全部新增 icon 字段("1.png" 等),侧边栏显示业务图标。 - 新增 step_outputs 缓存机制:每个 step 完成后把 output_path 写入 self.step_outputs。 - 新增 _sync_dependencies() 同步函数 + _safe_set_config() 包装器, 按依赖图把上游产物推给下游 view: step1 → step6 water_mask_path step3 → step4 / step6 / step10 deglint_img_path / bsq_path step4 → step9 sampling_csv_path step5 → step6 csv_path step6 → step7 / step8 training_csv_path step8 → step9 models_dir(父目录) step9 → step11 prediction_csv_dir / prediction_csv_path(双推) step10 → step11 geotiff_dir / geotiff_path(双推) 2. services/step1-13:统一输出解析器集成 - 新增 src/new/services/_output_resolver.py,提供 resolve_output_dir / copy_to_user_path / get_user_output_path / is_user_specified 四个共享工具。 - 每个 service 把原有的私有 _resolve_xxx_dir 改为调用 resolve_output_dir, 强制执行"用户优先"规则(用户指定 output_path 时用其父目录,否则用 work_dir/<subdir>)。 - 用户指定文件名 vs 底层硬编码文件名的"事后劫持"通过 copy_to_user_path 完成 (覆盖 step2、step4、step7、step8 等底层 step 不接受 output_path 关键字的步骤)。 3. views/step12_view.py:恢复 ImageCategoryTree + ImageViewerWidget 高级组件 - 删掉精简版占位 Label,挂回旧版的 ImageCategoryTree(按"模型评估/光谱分析/ 统计图表/处理结果/含量分布图"五类自动归类工作目录下的图像文件)。 - 挂回 ImageViewerWidget(滚轮缩放 0.1x-5x + 50ms 防抖 + FastTransformation/ SmoothTransformation 智能切换 + Ctrl+Wheel + 工具栏)。 - 扫描按钮接通 image_tree.scan_directory(),选中节点即时加载到 image_viewer。 - 按钮样式切换为 ModernStylesheet(success/primary)统一视觉。
2026-06-17 13:28:58 +08:00
from PyQt5.QtGui import QIcon, QPixmap
from PyQt5.QtWidgets import (
feat(new-arch):主窗口全功能增强(图标系统 + 全链路参数同步 + 服务输出统一解析 + Step12 分类浏览) 1. main_view.py:图标系统 + 全链路参数自动传导 - 新增 _res() 解析项目根的相对路径,PyInstaller 打包后兼容 sys._MEIPASS。 - 新增 QListWidgetItem / QMessageBox 导入,左侧导航列表支持右键菜单 + 错误弹窗。 - ROUTES 12 条全部新增 icon 字段("1.png" 等),侧边栏显示业务图标。 - 新增 step_outputs 缓存机制:每个 step 完成后把 output_path 写入 self.step_outputs。 - 新增 _sync_dependencies() 同步函数 + _safe_set_config() 包装器, 按依赖图把上游产物推给下游 view: step1 → step6 water_mask_path step3 → step4 / step6 / step10 deglint_img_path / bsq_path step4 → step9 sampling_csv_path step5 → step6 csv_path step6 → step7 / step8 training_csv_path step8 → step9 models_dir(父目录) step9 → step11 prediction_csv_dir / prediction_csv_path(双推) step10 → step11 geotiff_dir / geotiff_path(双推) 2. services/step1-13:统一输出解析器集成 - 新增 src/new/services/_output_resolver.py,提供 resolve_output_dir / copy_to_user_path / get_user_output_path / is_user_specified 四个共享工具。 - 每个 service 把原有的私有 _resolve_xxx_dir 改为调用 resolve_output_dir, 强制执行"用户优先"规则(用户指定 output_path 时用其父目录,否则用 work_dir/<subdir>)。 - 用户指定文件名 vs 底层硬编码文件名的"事后劫持"通过 copy_to_user_path 完成 (覆盖 step2、step4、step7、step8 等底层 step 不接受 output_path 关键字的步骤)。 3. views/step12_view.py:恢复 ImageCategoryTree + ImageViewerWidget 高级组件 - 删掉精简版占位 Label,挂回旧版的 ImageCategoryTree(按"模型评估/光谱分析/ 统计图表/处理结果/含量分布图"五类自动归类工作目录下的图像文件)。 - 挂回 ImageViewerWidget(滚轮缩放 0.1x-5x + 50ms 防抖 + FastTransformation/ SmoothTransformation 智能切换 + Ctrl+Wheel + 工具栏)。 - 扫描按钮接通 image_tree.scan_directory(),选中节点即时加载到 image_viewer。 - 按钮样式切换为 ModernStylesheet(success/primary)统一视觉。
2026-06-17 13:28:58 +08:00
QFileDialog, QHBoxLayout, QLabel, QListWidget, QListWidgetItem,
QMainWindow, QMessageBox, QPushButton, QSplitter, QStackedWidget,
QTextEdit, QVBoxLayout, QWidget,
)
# 让 ``python src/new/main_view.py`` 直接运行时也能 import ``src.xxx``
_HERE = Path(__file__).resolve().parent # .../src/new
_SRC_ROOT = _HERE.parent # .../src
feat(new-arch):主窗口全功能增强(图标系统 + 全链路参数同步 + 服务输出统一解析 + Step12 分类浏览) 1. main_view.py:图标系统 + 全链路参数自动传导 - 新增 _res() 解析项目根的相对路径,PyInstaller 打包后兼容 sys._MEIPASS。 - 新增 QListWidgetItem / QMessageBox 导入,左侧导航列表支持右键菜单 + 错误弹窗。 - ROUTES 12 条全部新增 icon 字段("1.png" 等),侧边栏显示业务图标。 - 新增 step_outputs 缓存机制:每个 step 完成后把 output_path 写入 self.step_outputs。 - 新增 _sync_dependencies() 同步函数 + _safe_set_config() 包装器, 按依赖图把上游产物推给下游 view: step1 → step6 water_mask_path step3 → step4 / step6 / step10 deglint_img_path / bsq_path step4 → step9 sampling_csv_path step5 → step6 csv_path step6 → step7 / step8 training_csv_path step8 → step9 models_dir(父目录) step9 → step11 prediction_csv_dir / prediction_csv_path(双推) step10 → step11 geotiff_dir / geotiff_path(双推) 2. services/step1-13:统一输出解析器集成 - 新增 src/new/services/_output_resolver.py,提供 resolve_output_dir / copy_to_user_path / get_user_output_path / is_user_specified 四个共享工具。 - 每个 service 把原有的私有 _resolve_xxx_dir 改为调用 resolve_output_dir, 强制执行"用户优先"规则(用户指定 output_path 时用其父目录,否则用 work_dir/<subdir>)。 - 用户指定文件名 vs 底层硬编码文件名的"事后劫持"通过 copy_to_user_path 完成 (覆盖 step2、step4、step7、step8 等底层 step 不接受 output_path 关键字的步骤)。 3. views/step12_view.py:恢复 ImageCategoryTree + ImageViewerWidget 高级组件 - 删掉精简版占位 Label,挂回旧版的 ImageCategoryTree(按"模型评估/光谱分析/ 统计图表/处理结果/含量分布图"五类自动归类工作目录下的图像文件)。 - 挂回 ImageViewerWidget(滚轮缩放 0.1x-5x + 50ms 防抖 + FastTransformation/ SmoothTransformation 智能切换 + Ctrl+Wheel + 工具栏)。 - 扫描按钮接通 image_tree.scan_directory(),选中节点即时加载到 image_viewer。 - 按钮样式切换为 ModernStylesheet(success/primary)统一视觉。
2026-06-17 13:28:58 +08:00
_PROJECT_ROOT = _SRC_ROOT.parent # .../WQ_GUI(项目根,用于解析 data/icons/)
if str(_SRC_ROOT) not in sys.path:
sys.path.insert(0, str(_SRC_ROOT))
feat(new-arch):主窗口全功能增强(图标系统 + 全链路参数同步 + 服务输出统一解析 + Step12 分类浏览) 1. main_view.py:图标系统 + 全链路参数自动传导 - 新增 _res() 解析项目根的相对路径,PyInstaller 打包后兼容 sys._MEIPASS。 - 新增 QListWidgetItem / QMessageBox 导入,左侧导航列表支持右键菜单 + 错误弹窗。 - ROUTES 12 条全部新增 icon 字段("1.png" 等),侧边栏显示业务图标。 - 新增 step_outputs 缓存机制:每个 step 完成后把 output_path 写入 self.step_outputs。 - 新增 _sync_dependencies() 同步函数 + _safe_set_config() 包装器, 按依赖图把上游产物推给下游 view: step1 → step6 water_mask_path step3 → step4 / step6 / step10 deglint_img_path / bsq_path step4 → step9 sampling_csv_path step5 → step6 csv_path step6 → step7 / step8 training_csv_path step8 → step9 models_dir(父目录) step9 → step11 prediction_csv_dir / prediction_csv_path(双推) step10 → step11 geotiff_dir / geotiff_path(双推) 2. services/step1-13:统一输出解析器集成 - 新增 src/new/services/_output_resolver.py,提供 resolve_output_dir / copy_to_user_path / get_user_output_path / is_user_specified 四个共享工具。 - 每个 service 把原有的私有 _resolve_xxx_dir 改为调用 resolve_output_dir, 强制执行"用户优先"规则(用户指定 output_path 时用其父目录,否则用 work_dir/<subdir>)。 - 用户指定文件名 vs 底层硬编码文件名的"事后劫持"通过 copy_to_user_path 完成 (覆盖 step2、step4、step7、step8 等底层 step 不接受 output_path 关键字的步骤)。 3. views/step12_view.py:恢复 ImageCategoryTree + ImageViewerWidget 高级组件 - 删掉精简版占位 Label,挂回旧版的 ImageCategoryTree(按"模型评估/光谱分析/ 统计图表/处理结果/含量分布图"五类自动归类工作目录下的图像文件)。 - 挂回 ImageViewerWidget(滚轮缩放 0.1x-5x + 50ms 防抖 + FastTransformation/ SmoothTransformation 智能切换 + Ctrl+Wheel + 工具栏)。 - 扫描按钮接通 image_tree.scan_directory(),选中节点即时加载到 image_viewer。 - 按钮样式切换为 ModernStylesheet(success/primary)统一视觉。
2026-06-17 13:28:58 +08:00
def _res(rel: str) -> str:
"""解析项目根的相对路径,PyInstaller 打包后兼容 sys._MEIPASS。"""
if hasattr(sys, "_MEIPASS"):
return os.path.join(sys._MEIPASS, rel)
return str(_PROJECT_ROOT / rel)
from src.gui.styles import ModernStylesheet
from src.new.views.placeholder_view import PlaceholderView
# =========================================================================
# 路由注册表:每条路由对应一对 view + service
# =========================================================================
ROUTES = [
{
"id": "step1",
"name": "1. 水域掩膜",
feat(new-arch):主窗口全功能增强(图标系统 + 全链路参数同步 + 服务输出统一解析 + Step12 分类浏览) 1. main_view.py:图标系统 + 全链路参数自动传导 - 新增 _res() 解析项目根的相对路径,PyInstaller 打包后兼容 sys._MEIPASS。 - 新增 QListWidgetItem / QMessageBox 导入,左侧导航列表支持右键菜单 + 错误弹窗。 - ROUTES 12 条全部新增 icon 字段("1.png" 等),侧边栏显示业务图标。 - 新增 step_outputs 缓存机制:每个 step 完成后把 output_path 写入 self.step_outputs。 - 新增 _sync_dependencies() 同步函数 + _safe_set_config() 包装器, 按依赖图把上游产物推给下游 view: step1 → step6 water_mask_path step3 → step4 / step6 / step10 deglint_img_path / bsq_path step4 → step9 sampling_csv_path step5 → step6 csv_path step6 → step7 / step8 training_csv_path step8 → step9 models_dir(父目录) step9 → step11 prediction_csv_dir / prediction_csv_path(双推) step10 → step11 geotiff_dir / geotiff_path(双推) 2. services/step1-13:统一输出解析器集成 - 新增 src/new/services/_output_resolver.py,提供 resolve_output_dir / copy_to_user_path / get_user_output_path / is_user_specified 四个共享工具。 - 每个 service 把原有的私有 _resolve_xxx_dir 改为调用 resolve_output_dir, 强制执行"用户优先"规则(用户指定 output_path 时用其父目录,否则用 work_dir/<subdir>)。 - 用户指定文件名 vs 底层硬编码文件名的"事后劫持"通过 copy_to_user_path 完成 (覆盖 step2、step4、step7、step8 等底层 step 不接受 output_path 关键字的步骤)。 3. views/step12_view.py:恢复 ImageCategoryTree + ImageViewerWidget 高级组件 - 删掉精简版占位 Label,挂回旧版的 ImageCategoryTree(按"模型评估/光谱分析/ 统计图表/处理结果/含量分布图"五类自动归类工作目录下的图像文件)。 - 挂回 ImageViewerWidget(滚轮缩放 0.1x-5x + 50ms 防抖 + FastTransformation/ SmoothTransformation 智能切换 + Ctrl+Wheel + 工具栏)。 - 扫描按钮接通 image_tree.scan_directory(),选中节点即时加载到 image_viewer。 - 按钮样式切换为 ModernStylesheet(success/primary)统一视觉。
2026-06-17 13:28:58 +08:00
"icon": "1.png",
"view_module": "src.new.views.step1_view",
"view_class": "Step1View",
"service_module": "src.new.services.step1_service",
"service_func": "execute_step1",
},
# -------- 业务路由(前 4 个预处理步骤已迁移到真实 service) --------
{
"id": "step2",
"name": "2. 耀斑检测",
feat(new-arch):主窗口全功能增强(图标系统 + 全链路参数同步 + 服务输出统一解析 + Step12 分类浏览) 1. main_view.py:图标系统 + 全链路参数自动传导 - 新增 _res() 解析项目根的相对路径,PyInstaller 打包后兼容 sys._MEIPASS。 - 新增 QListWidgetItem / QMessageBox 导入,左侧导航列表支持右键菜单 + 错误弹窗。 - ROUTES 12 条全部新增 icon 字段("1.png" 等),侧边栏显示业务图标。 - 新增 step_outputs 缓存机制:每个 step 完成后把 output_path 写入 self.step_outputs。 - 新增 _sync_dependencies() 同步函数 + _safe_set_config() 包装器, 按依赖图把上游产物推给下游 view: step1 → step6 water_mask_path step3 → step4 / step6 / step10 deglint_img_path / bsq_path step4 → step9 sampling_csv_path step5 → step6 csv_path step6 → step7 / step8 training_csv_path step8 → step9 models_dir(父目录) step9 → step11 prediction_csv_dir / prediction_csv_path(双推) step10 → step11 geotiff_dir / geotiff_path(双推) 2. services/step1-13:统一输出解析器集成 - 新增 src/new/services/_output_resolver.py,提供 resolve_output_dir / copy_to_user_path / get_user_output_path / is_user_specified 四个共享工具。 - 每个 service 把原有的私有 _resolve_xxx_dir 改为调用 resolve_output_dir, 强制执行"用户优先"规则(用户指定 output_path 时用其父目录,否则用 work_dir/<subdir>)。 - 用户指定文件名 vs 底层硬编码文件名的"事后劫持"通过 copy_to_user_path 完成 (覆盖 step2、step4、step7、step8 等底层 step 不接受 output_path 关键字的步骤)。 3. views/step12_view.py:恢复 ImageCategoryTree + ImageViewerWidget 高级组件 - 删掉精简版占位 Label,挂回旧版的 ImageCategoryTree(按"模型评估/光谱分析/ 统计图表/处理结果/含量分布图"五类自动归类工作目录下的图像文件)。 - 挂回 ImageViewerWidget(滚轮缩放 0.1x-5x + 50ms 防抖 + FastTransformation/ SmoothTransformation 智能切换 + Ctrl+Wheel + 工具栏)。 - 扫描按钮接通 image_tree.scan_directory(),选中节点即时加载到 image_viewer。 - 按钮样式切换为 ModernStylesheet(success/primary)统一视觉。
2026-06-17 13:28:58 +08:00
"icon": "2.png",
"view_module": "src.new.views.step2_view",
"view_class": "Step2View",
"service_module": "src.new.services.step2_service",
"service_func": "execute_step2",
},
{
"id": "step3",
"name": "3. 耀斑去除",
feat(new-arch):主窗口全功能增强(图标系统 + 全链路参数同步 + 服务输出统一解析 + Step12 分类浏览) 1. main_view.py:图标系统 + 全链路参数自动传导 - 新增 _res() 解析项目根的相对路径,PyInstaller 打包后兼容 sys._MEIPASS。 - 新增 QListWidgetItem / QMessageBox 导入,左侧导航列表支持右键菜单 + 错误弹窗。 - ROUTES 12 条全部新增 icon 字段("1.png" 等),侧边栏显示业务图标。 - 新增 step_outputs 缓存机制:每个 step 完成后把 output_path 写入 self.step_outputs。 - 新增 _sync_dependencies() 同步函数 + _safe_set_config() 包装器, 按依赖图把上游产物推给下游 view: step1 → step6 water_mask_path step3 → step4 / step6 / step10 deglint_img_path / bsq_path step4 → step9 sampling_csv_path step5 → step6 csv_path step6 → step7 / step8 training_csv_path step8 → step9 models_dir(父目录) step9 → step11 prediction_csv_dir / prediction_csv_path(双推) step10 → step11 geotiff_dir / geotiff_path(双推) 2. services/step1-13:统一输出解析器集成 - 新增 src/new/services/_output_resolver.py,提供 resolve_output_dir / copy_to_user_path / get_user_output_path / is_user_specified 四个共享工具。 - 每个 service 把原有的私有 _resolve_xxx_dir 改为调用 resolve_output_dir, 强制执行"用户优先"规则(用户指定 output_path 时用其父目录,否则用 work_dir/<subdir>)。 - 用户指定文件名 vs 底层硬编码文件名的"事后劫持"通过 copy_to_user_path 完成 (覆盖 step2、step4、step7、step8 等底层 step 不接受 output_path 关键字的步骤)。 3. views/step12_view.py:恢复 ImageCategoryTree + ImageViewerWidget 高级组件 - 删掉精简版占位 Label,挂回旧版的 ImageCategoryTree(按"模型评估/光谱分析/ 统计图表/处理结果/含量分布图"五类自动归类工作目录下的图像文件)。 - 挂回 ImageViewerWidget(滚轮缩放 0.1x-5x + 50ms 防抖 + FastTransformation/ SmoothTransformation 智能切换 + Ctrl+Wheel + 工具栏)。 - 扫描按钮接通 image_tree.scan_directory(),选中节点即时加载到 image_viewer。 - 按钮样式切换为 ModernStylesheet(success/primary)统一视觉。
2026-06-17 13:28:58 +08:00
"icon": "3.png",
"view_module": "src.new.views.step3_view",
"view_class": "Step3View",
"service_module": "src.new.services.step3_service",
"service_func": "execute_step3",
},
{
"id": "step4",
"name": "4. 采样点布设",
feat(new-arch):主窗口全功能增强(图标系统 + 全链路参数同步 + 服务输出统一解析 + Step12 分类浏览) 1. main_view.py:图标系统 + 全链路参数自动传导 - 新增 _res() 解析项目根的相对路径,PyInstaller 打包后兼容 sys._MEIPASS。 - 新增 QListWidgetItem / QMessageBox 导入,左侧导航列表支持右键菜单 + 错误弹窗。 - ROUTES 12 条全部新增 icon 字段("1.png" 等),侧边栏显示业务图标。 - 新增 step_outputs 缓存机制:每个 step 完成后把 output_path 写入 self.step_outputs。 - 新增 _sync_dependencies() 同步函数 + _safe_set_config() 包装器, 按依赖图把上游产物推给下游 view: step1 → step6 water_mask_path step3 → step4 / step6 / step10 deglint_img_path / bsq_path step4 → step9 sampling_csv_path step5 → step6 csv_path step6 → step7 / step8 training_csv_path step8 → step9 models_dir(父目录) step9 → step11 prediction_csv_dir / prediction_csv_path(双推) step10 → step11 geotiff_dir / geotiff_path(双推) 2. services/step1-13:统一输出解析器集成 - 新增 src/new/services/_output_resolver.py,提供 resolve_output_dir / copy_to_user_path / get_user_output_path / is_user_specified 四个共享工具。 - 每个 service 把原有的私有 _resolve_xxx_dir 改为调用 resolve_output_dir, 强制执行"用户优先"规则(用户指定 output_path 时用其父目录,否则用 work_dir/<subdir>)。 - 用户指定文件名 vs 底层硬编码文件名的"事后劫持"通过 copy_to_user_path 完成 (覆盖 step2、step4、step7、step8 等底层 step 不接受 output_path 关键字的步骤)。 3. views/step12_view.py:恢复 ImageCategoryTree + ImageViewerWidget 高级组件 - 删掉精简版占位 Label,挂回旧版的 ImageCategoryTree(按"模型评估/光谱分析/ 统计图表/处理结果/含量分布图"五类自动归类工作目录下的图像文件)。 - 挂回 ImageViewerWidget(滚轮缩放 0.1x-5x + 50ms 防抖 + FastTransformation/ SmoothTransformation 智能切换 + Ctrl+Wheel + 工具栏)。 - 扫描按钮接通 image_tree.scan_directory(),选中节点即时加载到 image_viewer。 - 按钮样式切换为 ModernStylesheet(success/primary)统一视觉。
2026-06-17 13:28:58 +08:00
"icon": "4.png",
"view_module": "src.new.views.step4_view",
"view_class": "Step4View",
"service_module": "src.new.services.step4_service",
"service_func": "execute_step4",
},
{
"id": "step5",
"name": "5. 数据清洗",
feat(new-arch):主窗口全功能增强(图标系统 + 全链路参数同步 + 服务输出统一解析 + Step12 分类浏览) 1. main_view.py:图标系统 + 全链路参数自动传导 - 新增 _res() 解析项目根的相对路径,PyInstaller 打包后兼容 sys._MEIPASS。 - 新增 QListWidgetItem / QMessageBox 导入,左侧导航列表支持右键菜单 + 错误弹窗。 - ROUTES 12 条全部新增 icon 字段("1.png" 等),侧边栏显示业务图标。 - 新增 step_outputs 缓存机制:每个 step 完成后把 output_path 写入 self.step_outputs。 - 新增 _sync_dependencies() 同步函数 + _safe_set_config() 包装器, 按依赖图把上游产物推给下游 view: step1 → step6 water_mask_path step3 → step4 / step6 / step10 deglint_img_path / bsq_path step4 → step9 sampling_csv_path step5 → step6 csv_path step6 → step7 / step8 training_csv_path step8 → step9 models_dir(父目录) step9 → step11 prediction_csv_dir / prediction_csv_path(双推) step10 → step11 geotiff_dir / geotiff_path(双推) 2. services/step1-13:统一输出解析器集成 - 新增 src/new/services/_output_resolver.py,提供 resolve_output_dir / copy_to_user_path / get_user_output_path / is_user_specified 四个共享工具。 - 每个 service 把原有的私有 _resolve_xxx_dir 改为调用 resolve_output_dir, 强制执行"用户优先"规则(用户指定 output_path 时用其父目录,否则用 work_dir/<subdir>)。 - 用户指定文件名 vs 底层硬编码文件名的"事后劫持"通过 copy_to_user_path 完成 (覆盖 step2、step4、step7、step8 等底层 step 不接受 output_path 关键字的步骤)。 3. views/step12_view.py:恢复 ImageCategoryTree + ImageViewerWidget 高级组件 - 删掉精简版占位 Label,挂回旧版的 ImageCategoryTree(按"模型评估/光谱分析/ 统计图表/处理结果/含量分布图"五类自动归类工作目录下的图像文件)。 - 挂回 ImageViewerWidget(滚轮缩放 0.1x-5x + 50ms 防抖 + FastTransformation/ SmoothTransformation 智能切换 + Ctrl+Wheel + 工具栏)。 - 扫描按钮接通 image_tree.scan_directory(),选中节点即时加载到 image_viewer。 - 按钮样式切换为 ModernStylesheet(success/primary)统一视觉。
2026-06-17 13:28:58 +08:00
"icon": "5.png",
"view_module": "src.new.views.step5_view",
"view_class": "Step5View",
"service_module": "src.new.services.step5_service",
"service_func": "execute_step5",
},
{
"id": "step6",
"name": "6. 光谱特征",
feat(new-arch):主窗口全功能增强(图标系统 + 全链路参数同步 + 服务输出统一解析 + Step12 分类浏览) 1. main_view.py:图标系统 + 全链路参数自动传导 - 新增 _res() 解析项目根的相对路径,PyInstaller 打包后兼容 sys._MEIPASS。 - 新增 QListWidgetItem / QMessageBox 导入,左侧导航列表支持右键菜单 + 错误弹窗。 - ROUTES 12 条全部新增 icon 字段("1.png" 等),侧边栏显示业务图标。 - 新增 step_outputs 缓存机制:每个 step 完成后把 output_path 写入 self.step_outputs。 - 新增 _sync_dependencies() 同步函数 + _safe_set_config() 包装器, 按依赖图把上游产物推给下游 view: step1 → step6 water_mask_path step3 → step4 / step6 / step10 deglint_img_path / bsq_path step4 → step9 sampling_csv_path step5 → step6 csv_path step6 → step7 / step8 training_csv_path step8 → step9 models_dir(父目录) step9 → step11 prediction_csv_dir / prediction_csv_path(双推) step10 → step11 geotiff_dir / geotiff_path(双推) 2. services/step1-13:统一输出解析器集成 - 新增 src/new/services/_output_resolver.py,提供 resolve_output_dir / copy_to_user_path / get_user_output_path / is_user_specified 四个共享工具。 - 每个 service 把原有的私有 _resolve_xxx_dir 改为调用 resolve_output_dir, 强制执行"用户优先"规则(用户指定 output_path 时用其父目录,否则用 work_dir/<subdir>)。 - 用户指定文件名 vs 底层硬编码文件名的"事后劫持"通过 copy_to_user_path 完成 (覆盖 step2、step4、step7、step8 等底层 step 不接受 output_path 关键字的步骤)。 3. views/step12_view.py:恢复 ImageCategoryTree + ImageViewerWidget 高级组件 - 删掉精简版占位 Label,挂回旧版的 ImageCategoryTree(按"模型评估/光谱分析/ 统计图表/处理结果/含量分布图"五类自动归类工作目录下的图像文件)。 - 挂回 ImageViewerWidget(滚轮缩放 0.1x-5x + 50ms 防抖 + FastTransformation/ SmoothTransformation 智能切换 + Ctrl+Wheel + 工具栏)。 - 扫描按钮接通 image_tree.scan_directory(),选中节点即时加载到 image_viewer。 - 按钮样式切换为 ModernStylesheet(success/primary)统一视觉。
2026-06-17 13:28:58 +08:00
"icon": "6.png",
"view_module": "src.new.views.step6_view",
"view_class": "Step6View",
"service_module": "src.new.services.step6_service",
"service_func": "execute_step6",
},
{
"id": "step7",
"name": "7. 水质光谱指数",
feat(new-arch):主窗口全功能增强(图标系统 + 全链路参数同步 + 服务输出统一解析 + Step12 分类浏览) 1. main_view.py:图标系统 + 全链路参数自动传导 - 新增 _res() 解析项目根的相对路径,PyInstaller 打包后兼容 sys._MEIPASS。 - 新增 QListWidgetItem / QMessageBox 导入,左侧导航列表支持右键菜单 + 错误弹窗。 - ROUTES 12 条全部新增 icon 字段("1.png" 等),侧边栏显示业务图标。 - 新增 step_outputs 缓存机制:每个 step 完成后把 output_path 写入 self.step_outputs。 - 新增 _sync_dependencies() 同步函数 + _safe_set_config() 包装器, 按依赖图把上游产物推给下游 view: step1 → step6 water_mask_path step3 → step4 / step6 / step10 deglint_img_path / bsq_path step4 → step9 sampling_csv_path step5 → step6 csv_path step6 → step7 / step8 training_csv_path step8 → step9 models_dir(父目录) step9 → step11 prediction_csv_dir / prediction_csv_path(双推) step10 → step11 geotiff_dir / geotiff_path(双推) 2. services/step1-13:统一输出解析器集成 - 新增 src/new/services/_output_resolver.py,提供 resolve_output_dir / copy_to_user_path / get_user_output_path / is_user_specified 四个共享工具。 - 每个 service 把原有的私有 _resolve_xxx_dir 改为调用 resolve_output_dir, 强制执行"用户优先"规则(用户指定 output_path 时用其父目录,否则用 work_dir/<subdir>)。 - 用户指定文件名 vs 底层硬编码文件名的"事后劫持"通过 copy_to_user_path 完成 (覆盖 step2、step4、step7、step8 等底层 step 不接受 output_path 关键字的步骤)。 3. views/step12_view.py:恢复 ImageCategoryTree + ImageViewerWidget 高级组件 - 删掉精简版占位 Label,挂回旧版的 ImageCategoryTree(按"模型评估/光谱分析/ 统计图表/处理结果/含量分布图"五类自动归类工作目录下的图像文件)。 - 挂回 ImageViewerWidget(滚轮缩放 0.1x-5x + 50ms 防抖 + FastTransformation/ SmoothTransformation 智能切换 + Ctrl+Wheel + 工具栏)。 - 扫描按钮接通 image_tree.scan_directory(),选中节点即时加载到 image_viewer。 - 按钮样式切换为 ModernStylesheet(success/primary)统一视觉。
2026-06-17 13:28:58 +08:00
"icon": "7.png",
"view_module": "src.new.views.step7_view",
"view_class": "Step7View",
"service_module": "src.new.services.step7_service",
"service_func": "execute_step7",
},
{
"id": "step8",
"name": "8. 机器学习建模",
feat(new-arch):主窗口全功能增强(图标系统 + 全链路参数同步 + 服务输出统一解析 + Step12 分类浏览) 1. main_view.py:图标系统 + 全链路参数自动传导 - 新增 _res() 解析项目根的相对路径,PyInstaller 打包后兼容 sys._MEIPASS。 - 新增 QListWidgetItem / QMessageBox 导入,左侧导航列表支持右键菜单 + 错误弹窗。 - ROUTES 12 条全部新增 icon 字段("1.png" 等),侧边栏显示业务图标。 - 新增 step_outputs 缓存机制:每个 step 完成后把 output_path 写入 self.step_outputs。 - 新增 _sync_dependencies() 同步函数 + _safe_set_config() 包装器, 按依赖图把上游产物推给下游 view: step1 → step6 water_mask_path step3 → step4 / step6 / step10 deglint_img_path / bsq_path step4 → step9 sampling_csv_path step5 → step6 csv_path step6 → step7 / step8 training_csv_path step8 → step9 models_dir(父目录) step9 → step11 prediction_csv_dir / prediction_csv_path(双推) step10 → step11 geotiff_dir / geotiff_path(双推) 2. services/step1-13:统一输出解析器集成 - 新增 src/new/services/_output_resolver.py,提供 resolve_output_dir / copy_to_user_path / get_user_output_path / is_user_specified 四个共享工具。 - 每个 service 把原有的私有 _resolve_xxx_dir 改为调用 resolve_output_dir, 强制执行"用户优先"规则(用户指定 output_path 时用其父目录,否则用 work_dir/<subdir>)。 - 用户指定文件名 vs 底层硬编码文件名的"事后劫持"通过 copy_to_user_path 完成 (覆盖 step2、step4、step7、step8 等底层 step 不接受 output_path 关键字的步骤)。 3. views/step12_view.py:恢复 ImageCategoryTree + ImageViewerWidget 高级组件 - 删掉精简版占位 Label,挂回旧版的 ImageCategoryTree(按"模型评估/光谱分析/ 统计图表/处理结果/含量分布图"五类自动归类工作目录下的图像文件)。 - 挂回 ImageViewerWidget(滚轮缩放 0.1x-5x + 50ms 防抖 + FastTransformation/ SmoothTransformation 智能切换 + Ctrl+Wheel + 工具栏)。 - 扫描按钮接通 image_tree.scan_directory(),选中节点即时加载到 image_viewer。 - 按钮样式切换为 ModernStylesheet(success/primary)统一视觉。
2026-06-17 13:28:58 +08:00
"icon": "8.png",
"view_module": "src.new.views.step8_view",
"view_class": "Step8View",
"service_module": "src.new.services.step8_service",
"service_func": "execute_step8",
},
{
feat(new-arch):主窗口全功能增强(图标系统 + 全链路参数同步 + 服务输出统一解析 + Step12 分类浏览) 1. main_view.py:图标系统 + 全链路参数自动传导 - 新增 _res() 解析项目根的相对路径,PyInstaller 打包后兼容 sys._MEIPASS。 - 新增 QListWidgetItem / QMessageBox 导入,左侧导航列表支持右键菜单 + 错误弹窗。 - ROUTES 12 条全部新增 icon 字段("1.png" 等),侧边栏显示业务图标。 - 新增 step_outputs 缓存机制:每个 step 完成后把 output_path 写入 self.step_outputs。 - 新增 _sync_dependencies() 同步函数 + _safe_set_config() 包装器, 按依赖图把上游产物推给下游 view: step1 → step6 water_mask_path step3 → step4 / step6 / step10 deglint_img_path / bsq_path step4 → step9 sampling_csv_path step5 → step6 csv_path step6 → step7 / step8 training_csv_path step8 → step9 models_dir(父目录) step9 → step11 prediction_csv_dir / prediction_csv_path(双推) step10 → step11 geotiff_dir / geotiff_path(双推) 2. services/step1-13:统一输出解析器集成 - 新增 src/new/services/_output_resolver.py,提供 resolve_output_dir / copy_to_user_path / get_user_output_path / is_user_specified 四个共享工具。 - 每个 service 把原有的私有 _resolve_xxx_dir 改为调用 resolve_output_dir, 强制执行"用户优先"规则(用户指定 output_path 时用其父目录,否则用 work_dir/<subdir>)。 - 用户指定文件名 vs 底层硬编码文件名的"事后劫持"通过 copy_to_user_path 完成 (覆盖 step2、step4、step7、step8 等底层 step 不接受 output_path 关键字的步骤)。 3. views/step12_view.py:恢复 ImageCategoryTree + ImageViewerWidget 高级组件 - 删掉精简版占位 Label,挂回旧版的 ImageCategoryTree(按"模型评估/光谱分析/ 统计图表/处理结果/含量分布图"五类自动归类工作目录下的图像文件)。 - 挂回 ImageViewerWidget(滚轮缩放 0.1x-5x + 50ms 防抖 + FastTransformation/ SmoothTransformation 智能切换 + Ctrl+Wheel + 工具栏)。 - 扫描按钮接通 image_tree.scan_directory(),选中节点即时加载到 image_viewer。 - 按钮样式切换为 ModernStylesheet(success/primary)统一视觉。
2026-06-17 13:28:58 +08:00
# 旧版共用 10.png 是 bug;data/icons/ 里有 11.png 一直未引用,正好给"预测"用
"id": "step9",
"name": "9. 机器学习预测",
feat(new-arch):主窗口全功能增强(图标系统 + 全链路参数同步 + 服务输出统一解析 + Step12 分类浏览) 1. main_view.py:图标系统 + 全链路参数自动传导 - 新增 _res() 解析项目根的相对路径,PyInstaller 打包后兼容 sys._MEIPASS。 - 新增 QListWidgetItem / QMessageBox 导入,左侧导航列表支持右键菜单 + 错误弹窗。 - ROUTES 12 条全部新增 icon 字段("1.png" 等),侧边栏显示业务图标。 - 新增 step_outputs 缓存机制:每个 step 完成后把 output_path 写入 self.step_outputs。 - 新增 _sync_dependencies() 同步函数 + _safe_set_config() 包装器, 按依赖图把上游产物推给下游 view: step1 → step6 water_mask_path step3 → step4 / step6 / step10 deglint_img_path / bsq_path step4 → step9 sampling_csv_path step5 → step6 csv_path step6 → step7 / step8 training_csv_path step8 → step9 models_dir(父目录) step9 → step11 prediction_csv_dir / prediction_csv_path(双推) step10 → step11 geotiff_dir / geotiff_path(双推) 2. services/step1-13:统一输出解析器集成 - 新增 src/new/services/_output_resolver.py,提供 resolve_output_dir / copy_to_user_path / get_user_output_path / is_user_specified 四个共享工具。 - 每个 service 把原有的私有 _resolve_xxx_dir 改为调用 resolve_output_dir, 强制执行"用户优先"规则(用户指定 output_path 时用其父目录,否则用 work_dir/<subdir>)。 - 用户指定文件名 vs 底层硬编码文件名的"事后劫持"通过 copy_to_user_path 完成 (覆盖 step2、step4、step7、step8 等底层 step 不接受 output_path 关键字的步骤)。 3. views/step12_view.py:恢复 ImageCategoryTree + ImageViewerWidget 高级组件 - 删掉精简版占位 Label,挂回旧版的 ImageCategoryTree(按"模型评估/光谱分析/ 统计图表/处理结果/含量分布图"五类自动归类工作目录下的图像文件)。 - 挂回 ImageViewerWidget(滚轮缩放 0.1x-5x + 50ms 防抖 + FastTransformation/ SmoothTransformation 智能切换 + Ctrl+Wheel + 工具栏)。 - 扫描按钮接通 image_tree.scan_directory(),选中节点即时加载到 image_viewer。 - 按钮样式切换为 ModernStylesheet(success/primary)统一视觉。
2026-06-17 13:28:58 +08:00
"icon": "11.png",
"view_module": "src.new.views.step9_view",
"view_class": "Step9View",
"service_module": "src.new.services.step9_service",
"service_func": "execute_step9",
},
{
"id": "step10",
"name": "10. 水色指数反演",
feat(new-arch):主窗口全功能增强(图标系统 + 全链路参数同步 + 服务输出统一解析 + Step12 分类浏览) 1. main_view.py:图标系统 + 全链路参数自动传导 - 新增 _res() 解析项目根的相对路径,PyInstaller 打包后兼容 sys._MEIPASS。 - 新增 QListWidgetItem / QMessageBox 导入,左侧导航列表支持右键菜单 + 错误弹窗。 - ROUTES 12 条全部新增 icon 字段("1.png" 等),侧边栏显示业务图标。 - 新增 step_outputs 缓存机制:每个 step 完成后把 output_path 写入 self.step_outputs。 - 新增 _sync_dependencies() 同步函数 + _safe_set_config() 包装器, 按依赖图把上游产物推给下游 view: step1 → step6 water_mask_path step3 → step4 / step6 / step10 deglint_img_path / bsq_path step4 → step9 sampling_csv_path step5 → step6 csv_path step6 → step7 / step8 training_csv_path step8 → step9 models_dir(父目录) step9 → step11 prediction_csv_dir / prediction_csv_path(双推) step10 → step11 geotiff_dir / geotiff_path(双推) 2. services/step1-13:统一输出解析器集成 - 新增 src/new/services/_output_resolver.py,提供 resolve_output_dir / copy_to_user_path / get_user_output_path / is_user_specified 四个共享工具。 - 每个 service 把原有的私有 _resolve_xxx_dir 改为调用 resolve_output_dir, 强制执行"用户优先"规则(用户指定 output_path 时用其父目录,否则用 work_dir/<subdir>)。 - 用户指定文件名 vs 底层硬编码文件名的"事后劫持"通过 copy_to_user_path 完成 (覆盖 step2、step4、step7、step8 等底层 step 不接受 output_path 关键字的步骤)。 3. views/step12_view.py:恢复 ImageCategoryTree + ImageViewerWidget 高级组件 - 删掉精简版占位 Label,挂回旧版的 ImageCategoryTree(按"模型评估/光谱分析/ 统计图表/处理结果/含量分布图"五类自动归类工作目录下的图像文件)。 - 挂回 ImageViewerWidget(滚轮缩放 0.1x-5x + 50ms 防抖 + FastTransformation/ SmoothTransformation 智能切换 + Ctrl+Wheel + 工具栏)。 - 扫描按钮接通 image_tree.scan_directory(),选中节点即时加载到 image_viewer。 - 按钮样式切换为 ModernStylesheet(success/primary)统一视觉。
2026-06-17 13:28:58 +08:00
"icon": "10.png",
"view_module": "src.new.views.step10_view",
"view_class": "Step10View",
"service_module": "src.new.services.step10_service",
"service_func": "execute_step10",
},
{
feat(new-arch):主窗口全功能增强(图标系统 + 全链路参数同步 + 服务输出统一解析 + Step12 分类浏览) 1. main_view.py:图标系统 + 全链路参数自动传导 - 新增 _res() 解析项目根的相对路径,PyInstaller 打包后兼容 sys._MEIPASS。 - 新增 QListWidgetItem / QMessageBox 导入,左侧导航列表支持右键菜单 + 错误弹窗。 - ROUTES 12 条全部新增 icon 字段("1.png" 等),侧边栏显示业务图标。 - 新增 step_outputs 缓存机制:每个 step 完成后把 output_path 写入 self.step_outputs。 - 新增 _sync_dependencies() 同步函数 + _safe_set_config() 包装器, 按依赖图把上游产物推给下游 view: step1 → step6 water_mask_path step3 → step4 / step6 / step10 deglint_img_path / bsq_path step4 → step9 sampling_csv_path step5 → step6 csv_path step6 → step7 / step8 training_csv_path step8 → step9 models_dir(父目录) step9 → step11 prediction_csv_dir / prediction_csv_path(双推) step10 → step11 geotiff_dir / geotiff_path(双推) 2. services/step1-13:统一输出解析器集成 - 新增 src/new/services/_output_resolver.py,提供 resolve_output_dir / copy_to_user_path / get_user_output_path / is_user_specified 四个共享工具。 - 每个 service 把原有的私有 _resolve_xxx_dir 改为调用 resolve_output_dir, 强制执行"用户优先"规则(用户指定 output_path 时用其父目录,否则用 work_dir/<subdir>)。 - 用户指定文件名 vs 底层硬编码文件名的"事后劫持"通过 copy_to_user_path 完成 (覆盖 step2、step4、step7、step8 等底层 step 不接受 output_path 关键字的步骤)。 3. views/step12_view.py:恢复 ImageCategoryTree + ImageViewerWidget 高级组件 - 删掉精简版占位 Label,挂回旧版的 ImageCategoryTree(按"模型评估/光谱分析/ 统计图表/处理结果/含量分布图"五类自动归类工作目录下的图像文件)。 - 挂回 ImageViewerWidget(滚轮缩放 0.1x-5x + 50ms 防抖 + FastTransformation/ SmoothTransformation 智能切换 + Ctrl+Wheel + 工具栏)。 - 扫描按钮接通 image_tree.scan_directory(),选中节点即时加载到 image_viewer。 - 按钮样式切换为 ModernStylesheet(success/primary)统一视觉。
2026-06-17 13:28:58 +08:00
# data/icons/ 没有 12.png/13.png;Step11/12/13 暂时复用 9.png(11 个 png 对 13 个 step 必然有共用)
"id": "step11",
"name": "11. 专题图生成",
feat(new-arch):主窗口全功能增强(图标系统 + 全链路参数同步 + 服务输出统一解析 + Step12 分类浏览) 1. main_view.py:图标系统 + 全链路参数自动传导 - 新增 _res() 解析项目根的相对路径,PyInstaller 打包后兼容 sys._MEIPASS。 - 新增 QListWidgetItem / QMessageBox 导入,左侧导航列表支持右键菜单 + 错误弹窗。 - ROUTES 12 条全部新增 icon 字段("1.png" 等),侧边栏显示业务图标。 - 新增 step_outputs 缓存机制:每个 step 完成后把 output_path 写入 self.step_outputs。 - 新增 _sync_dependencies() 同步函数 + _safe_set_config() 包装器, 按依赖图把上游产物推给下游 view: step1 → step6 water_mask_path step3 → step4 / step6 / step10 deglint_img_path / bsq_path step4 → step9 sampling_csv_path step5 → step6 csv_path step6 → step7 / step8 training_csv_path step8 → step9 models_dir(父目录) step9 → step11 prediction_csv_dir / prediction_csv_path(双推) step10 → step11 geotiff_dir / geotiff_path(双推) 2. services/step1-13:统一输出解析器集成 - 新增 src/new/services/_output_resolver.py,提供 resolve_output_dir / copy_to_user_path / get_user_output_path / is_user_specified 四个共享工具。 - 每个 service 把原有的私有 _resolve_xxx_dir 改为调用 resolve_output_dir, 强制执行"用户优先"规则(用户指定 output_path 时用其父目录,否则用 work_dir/<subdir>)。 - 用户指定文件名 vs 底层硬编码文件名的"事后劫持"通过 copy_to_user_path 完成 (覆盖 step2、step4、step7、step8 等底层 step 不接受 output_path 关键字的步骤)。 3. views/step12_view.py:恢复 ImageCategoryTree + ImageViewerWidget 高级组件 - 删掉精简版占位 Label,挂回旧版的 ImageCategoryTree(按"模型评估/光谱分析/ 统计图表/处理结果/含量分布图"五类自动归类工作目录下的图像文件)。 - 挂回 ImageViewerWidget(滚轮缩放 0.1x-5x + 50ms 防抖 + FastTransformation/ SmoothTransformation 智能切换 + Ctrl+Wheel + 工具栏)。 - 扫描按钮接通 image_tree.scan_directory(),选中节点即时加载到 image_viewer。 - 按钮样式切换为 ModernStylesheet(success/primary)统一视觉。
2026-06-17 13:28:58 +08:00
"icon": "9.png",
"view_module": "src.new.views.step11_view",
"view_class": "Step11View",
"service_module": "src.new.services.step11_service",
"service_func": "execute_step11",
},
{
"id": "step12",
"name": "12. 可视化",
feat(new-arch):主窗口全功能增强(图标系统 + 全链路参数同步 + 服务输出统一解析 + Step12 分类浏览) 1. main_view.py:图标系统 + 全链路参数自动传导 - 新增 _res() 解析项目根的相对路径,PyInstaller 打包后兼容 sys._MEIPASS。 - 新增 QListWidgetItem / QMessageBox 导入,左侧导航列表支持右键菜单 + 错误弹窗。 - ROUTES 12 条全部新增 icon 字段("1.png" 等),侧边栏显示业务图标。 - 新增 step_outputs 缓存机制:每个 step 完成后把 output_path 写入 self.step_outputs。 - 新增 _sync_dependencies() 同步函数 + _safe_set_config() 包装器, 按依赖图把上游产物推给下游 view: step1 → step6 water_mask_path step3 → step4 / step6 / step10 deglint_img_path / bsq_path step4 → step9 sampling_csv_path step5 → step6 csv_path step6 → step7 / step8 training_csv_path step8 → step9 models_dir(父目录) step9 → step11 prediction_csv_dir / prediction_csv_path(双推) step10 → step11 geotiff_dir / geotiff_path(双推) 2. services/step1-13:统一输出解析器集成 - 新增 src/new/services/_output_resolver.py,提供 resolve_output_dir / copy_to_user_path / get_user_output_path / is_user_specified 四个共享工具。 - 每个 service 把原有的私有 _resolve_xxx_dir 改为调用 resolve_output_dir, 强制执行"用户优先"规则(用户指定 output_path 时用其父目录,否则用 work_dir/<subdir>)。 - 用户指定文件名 vs 底层硬编码文件名的"事后劫持"通过 copy_to_user_path 完成 (覆盖 step2、step4、step7、step8 等底层 step 不接受 output_path 关键字的步骤)。 3. views/step12_view.py:恢复 ImageCategoryTree + ImageViewerWidget 高级组件 - 删掉精简版占位 Label,挂回旧版的 ImageCategoryTree(按"模型评估/光谱分析/ 统计图表/处理结果/含量分布图"五类自动归类工作目录下的图像文件)。 - 挂回 ImageViewerWidget(滚轮缩放 0.1x-5x + 50ms 防抖 + FastTransformation/ SmoothTransformation 智能切换 + Ctrl+Wheel + 工具栏)。 - 扫描按钮接通 image_tree.scan_directory(),选中节点即时加载到 image_viewer。 - 按钮样式切换为 ModernStylesheet(success/primary)统一视觉。
2026-06-17 13:28:58 +08:00
"icon": "9.png",
"view_module": "src.new.views.step12_view",
"view_class": "Step12View",
"service_module": "src.new.services.step12_service",
"service_func": "execute_step12",
},
{
"id": "step13",
"name": "13. 报告生成",
feat(new-arch):主窗口全功能增强(图标系统 + 全链路参数同步 + 服务输出统一解析 + Step12 分类浏览) 1. main_view.py:图标系统 + 全链路参数自动传导 - 新增 _res() 解析项目根的相对路径,PyInstaller 打包后兼容 sys._MEIPASS。 - 新增 QListWidgetItem / QMessageBox 导入,左侧导航列表支持右键菜单 + 错误弹窗。 - ROUTES 12 条全部新增 icon 字段("1.png" 等),侧边栏显示业务图标。 - 新增 step_outputs 缓存机制:每个 step 完成后把 output_path 写入 self.step_outputs。 - 新增 _sync_dependencies() 同步函数 + _safe_set_config() 包装器, 按依赖图把上游产物推给下游 view: step1 → step6 water_mask_path step3 → step4 / step6 / step10 deglint_img_path / bsq_path step4 → step9 sampling_csv_path step5 → step6 csv_path step6 → step7 / step8 training_csv_path step8 → step9 models_dir(父目录) step9 → step11 prediction_csv_dir / prediction_csv_path(双推) step10 → step11 geotiff_dir / geotiff_path(双推) 2. services/step1-13:统一输出解析器集成 - 新增 src/new/services/_output_resolver.py,提供 resolve_output_dir / copy_to_user_path / get_user_output_path / is_user_specified 四个共享工具。 - 每个 service 把原有的私有 _resolve_xxx_dir 改为调用 resolve_output_dir, 强制执行"用户优先"规则(用户指定 output_path 时用其父目录,否则用 work_dir/<subdir>)。 - 用户指定文件名 vs 底层硬编码文件名的"事后劫持"通过 copy_to_user_path 完成 (覆盖 step2、step4、step7、step8 等底层 step 不接受 output_path 关键字的步骤)。 3. views/step12_view.py:恢复 ImageCategoryTree + ImageViewerWidget 高级组件 - 删掉精简版占位 Label,挂回旧版的 ImageCategoryTree(按"模型评估/光谱分析/ 统计图表/处理结果/含量分布图"五类自动归类工作目录下的图像文件)。 - 挂回 ImageViewerWidget(滚轮缩放 0.1x-5x + 50ms 防抖 + FastTransformation/ SmoothTransformation 智能切换 + Ctrl+Wheel + 工具栏)。 - 扫描按钮接通 image_tree.scan_directory(),选中节点即时加载到 image_viewer。 - 按钮样式切换为 ModernStylesheet(success/primary)统一视觉。
2026-06-17 13:28:58 +08:00
"icon": "9.png",
"view_module": "src.new.views.step13_view",
"view_class": "Step13View",
"service_module": "src.new.services.step13_service",
"service_func": "execute_step13",
},
]
feat(new-arch):主窗口全功能增强(图标系统 + 全链路参数同步 + 服务输出统一解析 + Step12 分类浏览) 1. main_view.py:图标系统 + 全链路参数自动传导 - 新增 _res() 解析项目根的相对路径,PyInstaller 打包后兼容 sys._MEIPASS。 - 新增 QListWidgetItem / QMessageBox 导入,左侧导航列表支持右键菜单 + 错误弹窗。 - ROUTES 12 条全部新增 icon 字段("1.png" 等),侧边栏显示业务图标。 - 新增 step_outputs 缓存机制:每个 step 完成后把 output_path 写入 self.step_outputs。 - 新增 _sync_dependencies() 同步函数 + _safe_set_config() 包装器, 按依赖图把上游产物推给下游 view: step1 → step6 water_mask_path step3 → step4 / step6 / step10 deglint_img_path / bsq_path step4 → step9 sampling_csv_path step5 → step6 csv_path step6 → step7 / step8 training_csv_path step8 → step9 models_dir(父目录) step9 → step11 prediction_csv_dir / prediction_csv_path(双推) step10 → step11 geotiff_dir / geotiff_path(双推) 2. services/step1-13:统一输出解析器集成 - 新增 src/new/services/_output_resolver.py,提供 resolve_output_dir / copy_to_user_path / get_user_output_path / is_user_specified 四个共享工具。 - 每个 service 把原有的私有 _resolve_xxx_dir 改为调用 resolve_output_dir, 强制执行"用户优先"规则(用户指定 output_path 时用其父目录,否则用 work_dir/<subdir>)。 - 用户指定文件名 vs 底层硬编码文件名的"事后劫持"通过 copy_to_user_path 完成 (覆盖 step2、step4、step7、step8 等底层 step 不接受 output_path 关键字的步骤)。 3. views/step12_view.py:恢复 ImageCategoryTree + ImageViewerWidget 高级组件 - 删掉精简版占位 Label,挂回旧版的 ImageCategoryTree(按"模型评估/光谱分析/ 统计图表/处理结果/含量分布图"五类自动归类工作目录下的图像文件)。 - 挂回 ImageViewerWidget(滚轮缩放 0.1x-5x + 50ms 防抖 + FastTransformation/ SmoothTransformation 智能切换 + Ctrl+Wheel + 工具栏)。 - 扫描按钮接通 image_tree.scan_directory(),选中节点即时加载到 image_viewer。 - 按钮样式切换为 ModernStylesheet(success/primary)统一视觉。
2026-06-17 13:28:58 +08:00
# =========================================================================
# 全局输入参数:用户在任意 step 导图后,广播给所有 view 自动填充
# =========================================================================
# 这些是各 view 关心的"上游产物 / 用户导入文件"key。任何一次 run_single_step
# 都会把 config_dict 中出现的非空值更新进 self.global_inputs,并全量广播。
# view.set_config 已实现"非空才覆盖"(避免回填空串覆盖上游有效值),
# 所以直接全量广播是安全的。
GLOBAL_INPUT_KEYS: tuple[str, ...] = (
# step1 入口
"img_path", # 原始 BSQ/DAT/TIF 影像
"mask_path", # 现有水域掩膜(shp / dat / tif)
# step2/3 输入
"water_mask_path", # step1 产出
# step3/4/6/10 输入
"deglint_img_path", # step3 产出
"bsq_path", # step10 用,等价 deglint_img_path
"hdr_path", # ENVI 头文件
# step4 输入
"glint_mask_path", # step2 耀斑掩膜
# step5/6 输入
"csv_path", # step5 产出
"boundary_path", # step6 水域掩膜别名
# step7/8 输入
"training_csv_path", # step6 产出
# step9 输入
"sampling_csv_path", # step4 产出
"models_dir", # step8 产出
# step10 输入
"formula_csv_path", # waterindex.csv
# step11 输入
"prediction_csv_path",
"prediction_csv_dir",
"geotiff_path",
"geotiff_dir",
)
# =========================================================================
# TaskWorker:QThread 后台执行器(三信号协议)
# =========================================================================
class TaskWorker(QThread):
"""后台执行 ``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 /
matplotlib 等原生扩展,主线程与子线程的 Qt 事件循环隔离更稳。
"""
log_msg = pyqtSignal(str)
finished = pyqtSignal(dict)
error = pyqtSignal(str)
def __init__(self, service_func, config: dict):
super().__init__()
self.service_func = service_func
self.config = config
def run(self):
func_name = getattr(self.service_func, "__name__", "<anonymous>")
self.log_msg.emit(f"[Worker] 启动 {func_name}")
try:
result = self.service_func(self.config)
except Exception as e: # noqa: BLE001 —— worker 兜底捕获所有未预期异常
tb = traceback.format_exc()
self.log_msg.emit(f"[Worker] 异常 {type(e).__name__}: {e}")
self.error.emit(f"{type(e).__name__}: {e}\n{tb}")
return
status = result.get("status", "unknown") if isinstance(result, dict) else "unknown"
self.log_msg.emit(f"[Worker] 完成,status={status}")
self.finished.emit(result)
# =========================================================================
# MainView:QMainWindow 路由壳
# =========================================================================
class MainView(QMainWindow):
"""新架构的轻量路由主窗口"""
def __init__(self):
super().__init__()
self.work_dir: str = ""
self._views: dict = {}
self._route_map: dict = {}
self.worker: TaskWorker | None = None
feat(new-arch):主窗口全功能增强(图标系统 + 全链路参数同步 + 服务输出统一解析 + Step12 分类浏览) 1. main_view.py:图标系统 + 全链路参数自动传导 - 新增 _res() 解析项目根的相对路径,PyInstaller 打包后兼容 sys._MEIPASS。 - 新增 QListWidgetItem / QMessageBox 导入,左侧导航列表支持右键菜单 + 错误弹窗。 - ROUTES 12 条全部新增 icon 字段("1.png" 等),侧边栏显示业务图标。 - 新增 step_outputs 缓存机制:每个 step 完成后把 output_path 写入 self.step_outputs。 - 新增 _sync_dependencies() 同步函数 + _safe_set_config() 包装器, 按依赖图把上游产物推给下游 view: step1 → step6 water_mask_path step3 → step4 / step6 / step10 deglint_img_path / bsq_path step4 → step9 sampling_csv_path step5 → step6 csv_path step6 → step7 / step8 training_csv_path step8 → step9 models_dir(父目录) step9 → step11 prediction_csv_dir / prediction_csv_path(双推) step10 → step11 geotiff_dir / geotiff_path(双推) 2. services/step1-13:统一输出解析器集成 - 新增 src/new/services/_output_resolver.py,提供 resolve_output_dir / copy_to_user_path / get_user_output_path / is_user_specified 四个共享工具。 - 每个 service 把原有的私有 _resolve_xxx_dir 改为调用 resolve_output_dir, 强制执行"用户优先"规则(用户指定 output_path 时用其父目录,否则用 work_dir/<subdir>)。 - 用户指定文件名 vs 底层硬编码文件名的"事后劫持"通过 copy_to_user_path 完成 (覆盖 step2、step4、step7、step8 等底层 step 不接受 output_path 关键字的步骤)。 3. views/step12_view.py:恢复 ImageCategoryTree + ImageViewerWidget 高级组件 - 删掉精简版占位 Label,挂回旧版的 ImageCategoryTree(按"模型评估/光谱分析/ 统计图表/处理结果/含量分布图"五类自动归类工作目录下的图像文件)。 - 挂回 ImageViewerWidget(滚轮缩放 0.1x-5x + 50ms 防抖 + FastTransformation/ SmoothTransformation 智能切换 + Ctrl+Wheel + 工具栏)。 - 扫描按钮接通 image_tree.scan_directory(),选中节点即时加载到 image_viewer。 - 按钮样式切换为 ModernStylesheet(success/primary)统一视觉。
2026-06-17 13:28:58 +08:00
# 各 step 的产出路径缓存(声明式路径流转的中枢)
self.step_outputs: dict = {}
# 全局输入参数广播:用户在任何 step 导图后,其他 step 自动同步
self.global_inputs: dict = {}
self.setWindowTitle("WQ_GUI 新架构 · 端到端模块化路由壳")
self.resize(1280, 800)
self.setStyleSheet(ModernStylesheet.get_main_stylesheet())
feat(new-arch):主窗口全功能增强(图标系统 + 全链路参数同步 + 服务输出统一解析 + Step12 分类浏览) 1. main_view.py:图标系统 + 全链路参数自动传导 - 新增 _res() 解析项目根的相对路径,PyInstaller 打包后兼容 sys._MEIPASS。 - 新增 QListWidgetItem / QMessageBox 导入,左侧导航列表支持右键菜单 + 错误弹窗。 - ROUTES 12 条全部新增 icon 字段("1.png" 等),侧边栏显示业务图标。 - 新增 step_outputs 缓存机制:每个 step 完成后把 output_path 写入 self.step_outputs。 - 新增 _sync_dependencies() 同步函数 + _safe_set_config() 包装器, 按依赖图把上游产物推给下游 view: step1 → step6 water_mask_path step3 → step4 / step6 / step10 deglint_img_path / bsq_path step4 → step9 sampling_csv_path step5 → step6 csv_path step6 → step7 / step8 training_csv_path step8 → step9 models_dir(父目录) step9 → step11 prediction_csv_dir / prediction_csv_path(双推) step10 → step11 geotiff_dir / geotiff_path(双推) 2. services/step1-13:统一输出解析器集成 - 新增 src/new/services/_output_resolver.py,提供 resolve_output_dir / copy_to_user_path / get_user_output_path / is_user_specified 四个共享工具。 - 每个 service 把原有的私有 _resolve_xxx_dir 改为调用 resolve_output_dir, 强制执行"用户优先"规则(用户指定 output_path 时用其父目录,否则用 work_dir/<subdir>)。 - 用户指定文件名 vs 底层硬编码文件名的"事后劫持"通过 copy_to_user_path 完成 (覆盖 step2、step4、step7、step8 等底层 step 不接受 output_path 关键字的步骤)。 3. views/step12_view.py:恢复 ImageCategoryTree + ImageViewerWidget 高级组件 - 删掉精简版占位 Label,挂回旧版的 ImageCategoryTree(按"模型评估/光谱分析/ 统计图表/处理结果/含量分布图"五类自动归类工作目录下的图像文件)。 - 挂回 ImageViewerWidget(滚轮缩放 0.1x-5x + 50ms 防抖 + FastTransformation/ SmoothTransformation 智能切换 + Ctrl+Wheel + 工具栏)。 - 扫描按钮接通 image_tree.scan_directory(),选中节点即时加载到 image_viewer。 - 按钮样式切换为 ModernStylesheet(success/primary)统一视觉。
2026-06-17 13:28:58 +08:00
# 设置窗口图标(旧版 water_quality_gui.py L1339-1340 用 uitubiao.ico)
ico_path = _res("data/icons-1/uitubiao.ico")
if Path(ico_path).is_file():
self.setWindowIcon(QIcon(ico_path))
self._build_ui()
self._build_routes()
self._log("[Boot] MainView 初始化完成")
self._log(f"[Boot] 已注册 {len(ROUTES)} 条路由(13 个 view 和 service 已全部打通真实链路!)")
# ------------------------------------------------------------------
# UI 布局:左侧导航 + 右侧 stacked + 底部日志
# ------------------------------------------------------------------
def _build_ui(self):
central = QWidget()
self.setCentralWidget(central)
outer = QVBoxLayout(central)
outer.setContentsMargins(8, 8, 8, 8)
feat(new-arch):主窗口全功能增强(图标系统 + 全链路参数同步 + 服务输出统一解析 + Step12 分类浏览) 1. main_view.py:图标系统 + 全链路参数自动传导 - 新增 _res() 解析项目根的相对路径,PyInstaller 打包后兼容 sys._MEIPASS。 - 新增 QListWidgetItem / QMessageBox 导入,左侧导航列表支持右键菜单 + 错误弹窗。 - ROUTES 12 条全部新增 icon 字段("1.png" 等),侧边栏显示业务图标。 - 新增 step_outputs 缓存机制:每个 step 完成后把 output_path 写入 self.step_outputs。 - 新增 _sync_dependencies() 同步函数 + _safe_set_config() 包装器, 按依赖图把上游产物推给下游 view: step1 → step6 water_mask_path step3 → step4 / step6 / step10 deglint_img_path / bsq_path step4 → step9 sampling_csv_path step5 → step6 csv_path step6 → step7 / step8 training_csv_path step8 → step9 models_dir(父目录) step9 → step11 prediction_csv_dir / prediction_csv_path(双推) step10 → step11 geotiff_dir / geotiff_path(双推) 2. services/step1-13:统一输出解析器集成 - 新增 src/new/services/_output_resolver.py,提供 resolve_output_dir / copy_to_user_path / get_user_output_path / is_user_specified 四个共享工具。 - 每个 service 把原有的私有 _resolve_xxx_dir 改为调用 resolve_output_dir, 强制执行"用户优先"规则(用户指定 output_path 时用其父目录,否则用 work_dir/<subdir>)。 - 用户指定文件名 vs 底层硬编码文件名的"事后劫持"通过 copy_to_user_path 完成 (覆盖 step2、step4、step7、step8 等底层 step 不接受 output_path 关键字的步骤)。 3. views/step12_view.py:恢复 ImageCategoryTree + ImageViewerWidget 高级组件 - 删掉精简版占位 Label,挂回旧版的 ImageCategoryTree(按"模型评估/光谱分析/ 统计图表/处理结果/含量分布图"五类自动归类工作目录下的图像文件)。 - 挂回 ImageViewerWidget(滚轮缩放 0.1x-5x + 50ms 防抖 + FastTransformation/ SmoothTransformation 智能切换 + Ctrl+Wheel + 工具栏)。 - 扫描按钮接通 image_tree.scan_directory(),选中节点即时加载到 image_viewer。 - 按钮样式切换为 ModernStylesheet(success/primary)统一视觉。
2026-06-17 13:28:58 +08:00
# ----- 顶部工具条:logo + 项目名 + 工作目录 + 设置按钮 -----
toolbar = QHBoxLayout()
feat(new-arch):主窗口全功能增强(图标系统 + 全链路参数同步 + 服务输出统一解析 + Step12 分类浏览) 1. main_view.py:图标系统 + 全链路参数自动传导 - 新增 _res() 解析项目根的相对路径,PyInstaller 打包后兼容 sys._MEIPASS。 - 新增 QListWidgetItem / QMessageBox 导入,左侧导航列表支持右键菜单 + 错误弹窗。 - ROUTES 12 条全部新增 icon 字段("1.png" 等),侧边栏显示业务图标。 - 新增 step_outputs 缓存机制:每个 step 完成后把 output_path 写入 self.step_outputs。 - 新增 _sync_dependencies() 同步函数 + _safe_set_config() 包装器, 按依赖图把上游产物推给下游 view: step1 → step6 water_mask_path step3 → step4 / step6 / step10 deglint_img_path / bsq_path step4 → step9 sampling_csv_path step5 → step6 csv_path step6 → step7 / step8 training_csv_path step8 → step9 models_dir(父目录) step9 → step11 prediction_csv_dir / prediction_csv_path(双推) step10 → step11 geotiff_dir / geotiff_path(双推) 2. services/step1-13:统一输出解析器集成 - 新增 src/new/services/_output_resolver.py,提供 resolve_output_dir / copy_to_user_path / get_user_output_path / is_user_specified 四个共享工具。 - 每个 service 把原有的私有 _resolve_xxx_dir 改为调用 resolve_output_dir, 强制执行"用户优先"规则(用户指定 output_path 时用其父目录,否则用 work_dir/<subdir>)。 - 用户指定文件名 vs 底层硬编码文件名的"事后劫持"通过 copy_to_user_path 完成 (覆盖 step2、step4、step7、step8 等底层 step 不接受 output_path 关键字的步骤)。 3. views/step12_view.py:恢复 ImageCategoryTree + ImageViewerWidget 高级组件 - 删掉精简版占位 Label,挂回旧版的 ImageCategoryTree(按"模型评估/光谱分析/ 统计图表/处理结果/含量分布图"五类自动归类工作目录下的图像文件)。 - 挂回 ImageViewerWidget(滚轮缩放 0.1x-5x + 50ms 防抖 + FastTransformation/ SmoothTransformation 智能切换 + Ctrl+Wheel + 工具栏)。 - 扫描按钮接通 image_tree.scan_directory(),选中节点即时加载到 image_viewer。 - 按钮样式切换为 ModernStylesheet(success/primary)统一视觉。
2026-06-17 13:28:58 +08:00
# Logo(旧版 water_quality_gui.py L1569 用 logo.png)
logo_path = _res("data/icons/logo.png")
if Path(logo_path).is_file():
logo_pixmap = QPixmap(logo_path)
if not logo_pixmap.isNull():
logo_pixmap = logo_pixmap.scaledToHeight(
36, Qt.SmoothTransformation
)
logo_label = QLabel()
logo_label.setPixmap(logo_pixmap)
toolbar.addWidget(logo_label)
# 项目名(紧贴 logo 右侧)
title_label = QLabel("WQ_GUI · 新架构")
title_label.setStyleSheet(
"font-size: 14px; font-weight: bold; color: #0055D4;"
)
toolbar.addWidget(title_label)
toolbar.addSpacing(20)
toolbar.addWidget(QLabel("工作目录:"))
self.work_dir_label = QLabel("(未设置)")
self.work_dir_label.setStyleSheet("color: #0055D4; font-weight: bold;")
toolbar.addWidget(self.work_dir_label, 1)
self.set_workdir_btn = QPushButton("设置工作目录...")
self.set_workdir_btn.setStyleSheet(ModernStylesheet.get_button_stylesheet("normal"))
self.set_workdir_btn.clicked.connect(self._on_set_workdir)
toolbar.addWidget(self.set_workdir_btn)
outer.addLayout(toolbar)
feat(new-arch):主窗口全功能增强(图标系统 + 全链路参数同步 + 服务输出统一解析 + Step12 分类浏览) 1. main_view.py:图标系统 + 全链路参数自动传导 - 新增 _res() 解析项目根的相对路径,PyInstaller 打包后兼容 sys._MEIPASS。 - 新增 QListWidgetItem / QMessageBox 导入,左侧导航列表支持右键菜单 + 错误弹窗。 - ROUTES 12 条全部新增 icon 字段("1.png" 等),侧边栏显示业务图标。 - 新增 step_outputs 缓存机制:每个 step 完成后把 output_path 写入 self.step_outputs。 - 新增 _sync_dependencies() 同步函数 + _safe_set_config() 包装器, 按依赖图把上游产物推给下游 view: step1 → step6 water_mask_path step3 → step4 / step6 / step10 deglint_img_path / bsq_path step4 → step9 sampling_csv_path step5 → step6 csv_path step6 → step7 / step8 training_csv_path step8 → step9 models_dir(父目录) step9 → step11 prediction_csv_dir / prediction_csv_path(双推) step10 → step11 geotiff_dir / geotiff_path(双推) 2. services/step1-13:统一输出解析器集成 - 新增 src/new/services/_output_resolver.py,提供 resolve_output_dir / copy_to_user_path / get_user_output_path / is_user_specified 四个共享工具。 - 每个 service 把原有的私有 _resolve_xxx_dir 改为调用 resolve_output_dir, 强制执行"用户优先"规则(用户指定 output_path 时用其父目录,否则用 work_dir/<subdir>)。 - 用户指定文件名 vs 底层硬编码文件名的"事后劫持"通过 copy_to_user_path 完成 (覆盖 step2、step4、step7、step8 等底层 step 不接受 output_path 关键字的步骤)。 3. views/step12_view.py:恢复 ImageCategoryTree + ImageViewerWidget 高级组件 - 删掉精简版占位 Label,挂回旧版的 ImageCategoryTree(按"模型评估/光谱分析/ 统计图表/处理结果/含量分布图"五类自动归类工作目录下的图像文件)。 - 挂回 ImageViewerWidget(滚轮缩放 0.1x-5x + 50ms 防抖 + FastTransformation/ SmoothTransformation 智能切换 + Ctrl+Wheel + 工具栏)。 - 扫描按钮接通 image_tree.scan_directory(),选中节点即时加载到 image_viewer。 - 按钮样式切换为 ModernStylesheet(success/primary)统一视觉。
2026-06-17 13:28:58 +08:00
# ----- 顶部 MegaCube Banner(CSS border-image 平铺拉伸 + 居中文字) -----
banner_label = QLabel()
banner_label.setMinimumHeight(100)
banner_label.setMaximumHeight(100)
banner_label.setAlignment(Qt.AlignCenter)
# 无条件显示文字(border-image 不会覆盖前景文字)
banner_label.setText("MegaCube-Water Quality V1.2")
banner_path = _res("data/icons/Mega Water 1.0.jpg").replace('\\', '/')
if Path(banner_path).is_file():
banner_label.setStyleSheet(
f"border-image: url('{banner_path}') 0 0 0 0 stretch stretch;"
"color: white; font-size: 38px; font-weight: bold; font-family: 'Microsoft YaHei';"
)
else:
banner_label.setStyleSheet(
"background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, "
"stop:0 #00a0e9, stop:1 #005a9e);"
"color: white; font-size: 38px; font-weight: bold; font-family: 'Microsoft YaHei';"
)
outer.addWidget(banner_label)
# ----- 中部:左导航 + 右 stacked(用 QSplitter 可拖动) -----
splitter = QSplitter(Qt.Horizontal)
self.nav_list = QListWidget()
self.nav_list.setStyleSheet(ModernStylesheet.get_sidebar_stylesheet())
self.nav_list.setFixedWidth(200)
self.nav_list.currentRowChanged.connect(self._on_nav_changed)
splitter.addWidget(self.nav_list)
self.stacked = QStackedWidget()
splitter.addWidget(self.stacked)
splitter.setStretchFactor(0, 0)
splitter.setStretchFactor(1, 1)
outer.addWidget(splitter, 1)
# ----- 底部日志 -----
self.log_text = QTextEdit()
self.log_text.setReadOnly(True)
self.log_text.setStyleSheet("background-color: #1E1E1E; color: #DCDCDC; font-family: Consolas, monospace;")
self.log_text.setFixedHeight(180)
outer.addWidget(self.log_text)
# ------------------------------------------------------------------
# 路由注册:实例化 view、填充 nav_list 与 stacked
# ------------------------------------------------------------------
def _build_routes(self):
for route in ROUTES:
self._route_map[route["id"]] = route
view = self._instantiate_view(route)
self._views[route["id"]] = view
self.stacked.addWidget(view)
feat(new-arch):主窗口全功能增强(图标系统 + 全链路参数同步 + 服务输出统一解析 + Step12 分类浏览) 1. main_view.py:图标系统 + 全链路参数自动传导 - 新增 _res() 解析项目根的相对路径,PyInstaller 打包后兼容 sys._MEIPASS。 - 新增 QListWidgetItem / QMessageBox 导入,左侧导航列表支持右键菜单 + 错误弹窗。 - ROUTES 12 条全部新增 icon 字段("1.png" 等),侧边栏显示业务图标。 - 新增 step_outputs 缓存机制:每个 step 完成后把 output_path 写入 self.step_outputs。 - 新增 _sync_dependencies() 同步函数 + _safe_set_config() 包装器, 按依赖图把上游产物推给下游 view: step1 → step6 water_mask_path step3 → step4 / step6 / step10 deglint_img_path / bsq_path step4 → step9 sampling_csv_path step5 → step6 csv_path step6 → step7 / step8 training_csv_path step8 → step9 models_dir(父目录) step9 → step11 prediction_csv_dir / prediction_csv_path(双推) step10 → step11 geotiff_dir / geotiff_path(双推) 2. services/step1-13:统一输出解析器集成 - 新增 src/new/services/_output_resolver.py,提供 resolve_output_dir / copy_to_user_path / get_user_output_path / is_user_specified 四个共享工具。 - 每个 service 把原有的私有 _resolve_xxx_dir 改为调用 resolve_output_dir, 强制执行"用户优先"规则(用户指定 output_path 时用其父目录,否则用 work_dir/<subdir>)。 - 用户指定文件名 vs 底层硬编码文件名的"事后劫持"通过 copy_to_user_path 完成 (覆盖 step2、step4、step7、step8 等底层 step 不接受 output_path 关键字的步骤)。 3. views/step12_view.py:恢复 ImageCategoryTree + ImageViewerWidget 高级组件 - 删掉精简版占位 Label,挂回旧版的 ImageCategoryTree(按"模型评估/光谱分析/ 统计图表/处理结果/含量分布图"五类自动归类工作目录下的图像文件)。 - 挂回 ImageViewerWidget(滚轮缩放 0.1x-5x + 50ms 防抖 + FastTransformation/ SmoothTransformation 智能切换 + Ctrl+Wheel + 工具栏)。 - 扫描按钮接通 image_tree.scan_directory(),选中节点即时加载到 image_viewer。 - 按钮样式切换为 ModernStylesheet(success/primary)统一视觉。
2026-06-17 13:28:58 +08:00
# 加载图标(ROUTES[icon] 字段);找不到图标时退化为无图标 item
icon_filename = route.get("icon")
if icon_filename:
icon_full_path = _res(f"data/icons/{icon_filename}")
if Path(icon_full_path).is_file():
item = QListWidgetItem(QIcon(icon_full_path), route["name"])
else:
self._log(
f"[Router] 图标缺失 {icon_full_path},{route['id']} 用纯文字"
)
item = QListWidgetItem(route["name"])
else:
item = QListWidgetItem(route["name"])
# 统一图标尺寸(避免不同 png 拉伸不一致)
item.setSizeHint(item.sizeHint())
self.nav_list.addItem(item)
if ROUTES:
self.nav_list.setCurrentRow(0)
def _instantiate_view(self, route: dict) -> QWidget:
"""根据路由表实例化 view:step1 走真实类,其余走 PlaceholderView"""
if route["view_module"] != "_placeholder":
try:
module = importlib.import_module(route["view_module"])
cls = getattr(module, route["view_class"])
return cls(self.stacked)
except Exception as e: # noqa: BLE001
# 真实 view 加载失败时降级为占位,并在日志区报错
self._log(f"[Router] 加载真实 view 失败 ({route['id']}): {e}")
traceback.print_exc()
# 占位 view:直接构造
return PlaceholderView(route["id"], route["name"], self.stacked)
# ------------------------------------------------------------------
# 导航切换
# ------------------------------------------------------------------
def _on_nav_changed(self, row: int):
if row < 0 or row >= len(ROUTES):
return
route = ROUTES[row]
view = self._views[route["id"]]
self.stacked.setCurrentWidget(view)
self._log(f"[Nav] 切换到 {route['id']} → {route['name']}")
# ------------------------------------------------------------------
# 工作目录推送:设置后广播给所有 view
# ------------------------------------------------------------------
def _on_set_workdir(self):
d = QFileDialog.getExistingDirectory(self, "选择工作目录", self.work_dir or "")
if not d:
return
self.set_work_dir(d)
def set_work_dir(self, work_dir: str):
"""设置工作目录并广播给所有 view"""
if not work_dir:
return
self.work_dir = work_dir.replace("\\", "/")
self.work_dir_label.setText(self.work_dir)
self._log(f"[Router] 工作目录已设置: {self.work_dir}")
feat(new-arch):主窗口全功能增强(图标系统 + 全链路参数同步 + 服务输出统一解析 + Step12 分类浏览) 1. main_view.py:图标系统 + 全链路参数自动传导 - 新增 _res() 解析项目根的相对路径,PyInstaller 打包后兼容 sys._MEIPASS。 - 新增 QListWidgetItem / QMessageBox 导入,左侧导航列表支持右键菜单 + 错误弹窗。 - ROUTES 12 条全部新增 icon 字段("1.png" 等),侧边栏显示业务图标。 - 新增 step_outputs 缓存机制:每个 step 完成后把 output_path 写入 self.step_outputs。 - 新增 _sync_dependencies() 同步函数 + _safe_set_config() 包装器, 按依赖图把上游产物推给下游 view: step1 → step6 water_mask_path step3 → step4 / step6 / step10 deglint_img_path / bsq_path step4 → step9 sampling_csv_path step5 → step6 csv_path step6 → step7 / step8 training_csv_path step8 → step9 models_dir(父目录) step9 → step11 prediction_csv_dir / prediction_csv_path(双推) step10 → step11 geotiff_dir / geotiff_path(双推) 2. services/step1-13:统一输出解析器集成 - 新增 src/new/services/_output_resolver.py,提供 resolve_output_dir / copy_to_user_path / get_user_output_path / is_user_specified 四个共享工具。 - 每个 service 把原有的私有 _resolve_xxx_dir 改为调用 resolve_output_dir, 强制执行"用户优先"规则(用户指定 output_path 时用其父目录,否则用 work_dir/<subdir>)。 - 用户指定文件名 vs 底层硬编码文件名的"事后劫持"通过 copy_to_user_path 完成 (覆盖 step2、step4、step7、step8 等底层 step 不接受 output_path 关键字的步骤)。 3. views/step12_view.py:恢复 ImageCategoryTree + ImageViewerWidget 高级组件 - 删掉精简版占位 Label,挂回旧版的 ImageCategoryTree(按"模型评估/光谱分析/ 统计图表/处理结果/含量分布图"五类自动归类工作目录下的图像文件)。 - 挂回 ImageViewerWidget(滚轮缩放 0.1x-5x + 50ms 防抖 + FastTransformation/ SmoothTransformation 智能切换 + Ctrl+Wheel + 工具栏)。 - 扫描按钮接通 image_tree.scan_directory(),选中节点即时加载到 image_viewer。 - 按钮样式切换为 ModernStylesheet(success/primary)统一视觉。
2026-06-17 13:28:58 +08:00
# 工作目录变更 → 清空全局输入缓存(旧路径可能已失效)
if self.global_inputs:
self.clear_global_inputs()
# 推送给所有 view(让它们按需自动填充路径)
for view in self._views.values():
if hasattr(view, "update_from_config"):
view.update_from_config(self.work_dir, pipeline=None)
# ------------------------------------------------------------------
# 核心调度:run_single_step(被 view.dispatch_execute 调用)
# ------------------------------------------------------------------
def run_single_step(self, step_id: str, config_dict: dict):
"""从 view 接收 ``(step_id, config)`` → 调度 service 后台执行
1. 查路由表;
2. 注入 ``work_dir``(避免 view 重复感知);
feat(new-arch):主窗口全功能增强(图标系统 + 全链路参数同步 + 服务输出统一解析 + Step12 分类浏览) 1. main_view.py:图标系统 + 全链路参数自动传导 - 新增 _res() 解析项目根的相对路径,PyInstaller 打包后兼容 sys._MEIPASS。 - 新增 QListWidgetItem / QMessageBox 导入,左侧导航列表支持右键菜单 + 错误弹窗。 - ROUTES 12 条全部新增 icon 字段("1.png" 等),侧边栏显示业务图标。 - 新增 step_outputs 缓存机制:每个 step 完成后把 output_path 写入 self.step_outputs。 - 新增 _sync_dependencies() 同步函数 + _safe_set_config() 包装器, 按依赖图把上游产物推给下游 view: step1 → step6 water_mask_path step3 → step4 / step6 / step10 deglint_img_path / bsq_path step4 → step9 sampling_csv_path step5 → step6 csv_path step6 → step7 / step8 training_csv_path step8 → step9 models_dir(父目录) step9 → step11 prediction_csv_dir / prediction_csv_path(双推) step10 → step11 geotiff_dir / geotiff_path(双推) 2. services/step1-13:统一输出解析器集成 - 新增 src/new/services/_output_resolver.py,提供 resolve_output_dir / copy_to_user_path / get_user_output_path / is_user_specified 四个共享工具。 - 每个 service 把原有的私有 _resolve_xxx_dir 改为调用 resolve_output_dir, 强制执行"用户优先"规则(用户指定 output_path 时用其父目录,否则用 work_dir/<subdir>)。 - 用户指定文件名 vs 底层硬编码文件名的"事后劫持"通过 copy_to_user_path 完成 (覆盖 step2、step4、step7、step8 等底层 step 不接受 output_path 关键字的步骤)。 3. views/step12_view.py:恢复 ImageCategoryTree + ImageViewerWidget 高级组件 - 删掉精简版占位 Label,挂回旧版的 ImageCategoryTree(按"模型评估/光谱分析/ 统计图表/处理结果/含量分布图"五类自动归类工作目录下的图像文件)。 - 挂回 ImageViewerWidget(滚轮缩放 0.1x-5x + 50ms 防抖 + FastTransformation/ SmoothTransformation 智能切换 + Ctrl+Wheel + 工具栏)。 - 扫描按钮接通 image_tree.scan_directory(),选中节点即时加载到 image_viewer。 - 按钮样式切换为 ModernStylesheet(success/primary)统一视觉。
2026-06-17 13:28:58 +08:00
3. **全局输入广播**——把本次 config_dict 中的公共输入 key 累计到
``self.global_inputs``,再推送给所有 view(实现"一处导入,全局共享");
4. 启动 ``TaskWorker`` 在子线程运行 service;
5. 三信号路由:log_msg → 日志框;finished → 状态分支日志;
error → 未预期异常写日志 + traceback。
"""
route = self._route_map.get(step_id)
if route is None:
self._log(f"[Router] 未知 step_id: {step_id}")
return
# 注入 work_dir(仅当 view 未带且 main_view 已配置时)
if self.work_dir and "work_dir" not in config_dict:
config_dict = {**config_dict, "work_dir": self.work_dir}
feat(new-arch):主窗口全功能增强(图标系统 + 全链路参数同步 + 服务输出统一解析 + Step12 分类浏览) 1. main_view.py:图标系统 + 全链路参数自动传导 - 新增 _res() 解析项目根的相对路径,PyInstaller 打包后兼容 sys._MEIPASS。 - 新增 QListWidgetItem / QMessageBox 导入,左侧导航列表支持右键菜单 + 错误弹窗。 - ROUTES 12 条全部新增 icon 字段("1.png" 等),侧边栏显示业务图标。 - 新增 step_outputs 缓存机制:每个 step 完成后把 output_path 写入 self.step_outputs。 - 新增 _sync_dependencies() 同步函数 + _safe_set_config() 包装器, 按依赖图把上游产物推给下游 view: step1 → step6 water_mask_path step3 → step4 / step6 / step10 deglint_img_path / bsq_path step4 → step9 sampling_csv_path step5 → step6 csv_path step6 → step7 / step8 training_csv_path step8 → step9 models_dir(父目录) step9 → step11 prediction_csv_dir / prediction_csv_path(双推) step10 → step11 geotiff_dir / geotiff_path(双推) 2. services/step1-13:统一输出解析器集成 - 新增 src/new/services/_output_resolver.py,提供 resolve_output_dir / copy_to_user_path / get_user_output_path / is_user_specified 四个共享工具。 - 每个 service 把原有的私有 _resolve_xxx_dir 改为调用 resolve_output_dir, 强制执行"用户优先"规则(用户指定 output_path 时用其父目录,否则用 work_dir/<subdir>)。 - 用户指定文件名 vs 底层硬编码文件名的"事后劫持"通过 copy_to_user_path 完成 (覆盖 step2、step4、step7、step8 等底层 step 不接受 output_path 关键字的步骤)。 3. views/step12_view.py:恢复 ImageCategoryTree + ImageViewerWidget 高级组件 - 删掉精简版占位 Label,挂回旧版的 ImageCategoryTree(按"模型评估/光谱分析/ 统计图表/处理结果/含量分布图"五类自动归类工作目录下的图像文件)。 - 挂回 ImageViewerWidget(滚轮缩放 0.1x-5x + 50ms 防抖 + FastTransformation/ SmoothTransformation 智能切换 + Ctrl+Wheel + 工具栏)。 - 扫描按钮接通 image_tree.scan_directory(),选中节点即时加载到 image_viewer。 - 按钮样式切换为 ModernStylesheet(success/primary)统一视觉。
2026-06-17 13:28:58 +08:00
# 全局输入广播:累计 + 推送给所有 view
self._broadcast_global_inputs(config_dict)
service_func = self._load_callable(route["service_module"], route["service_func"])
if service_func is None:
return
self._log(f"[Router] 收到 {step_id} 请求,配置: {config_dict}")
# 启动后台线程(覆盖旧 worker 防泄漏)
if self.worker and self.worker.isRunning():
self._log("[Router] 上一个任务尚未结束,丢弃新请求")
return
self.worker = TaskWorker(service_func, config_dict)
self.worker.log_msg.connect(self._log)
feat(new-arch):主窗口全功能增强(图标系统 + 全链路参数同步 + 服务输出统一解析 + Step12 分类浏览) 1. main_view.py:图标系统 + 全链路参数自动传导 - 新增 _res() 解析项目根的相对路径,PyInstaller 打包后兼容 sys._MEIPASS。 - 新增 QListWidgetItem / QMessageBox 导入,左侧导航列表支持右键菜单 + 错误弹窗。 - ROUTES 12 条全部新增 icon 字段("1.png" 等),侧边栏显示业务图标。 - 新增 step_outputs 缓存机制:每个 step 完成后把 output_path 写入 self.step_outputs。 - 新增 _sync_dependencies() 同步函数 + _safe_set_config() 包装器, 按依赖图把上游产物推给下游 view: step1 → step6 water_mask_path step3 → step4 / step6 / step10 deglint_img_path / bsq_path step4 → step9 sampling_csv_path step5 → step6 csv_path step6 → step7 / step8 training_csv_path step8 → step9 models_dir(父目录) step9 → step11 prediction_csv_dir / prediction_csv_path(双推) step10 → step11 geotiff_dir / geotiff_path(双推) 2. services/step1-13:统一输出解析器集成 - 新增 src/new/services/_output_resolver.py,提供 resolve_output_dir / copy_to_user_path / get_user_output_path / is_user_specified 四个共享工具。 - 每个 service 把原有的私有 _resolve_xxx_dir 改为调用 resolve_output_dir, 强制执行"用户优先"规则(用户指定 output_path 时用其父目录,否则用 work_dir/<subdir>)。 - 用户指定文件名 vs 底层硬编码文件名的"事后劫持"通过 copy_to_user_path 完成 (覆盖 step2、step4、step7、step8 等底层 step 不接受 output_path 关键字的步骤)。 3. views/step12_view.py:恢复 ImageCategoryTree + ImageViewerWidget 高级组件 - 删掉精简版占位 Label,挂回旧版的 ImageCategoryTree(按"模型评估/光谱分析/ 统计图表/处理结果/含量分布图"五类自动归类工作目录下的图像文件)。 - 挂回 ImageViewerWidget(滚轮缩放 0.1x-5x + 50ms 防抖 + FastTransformation/ SmoothTransformation 智能切换 + Ctrl+Wheel + 工具栏)。 - 扫描按钮接通 image_tree.scan_directory(),选中节点即时加载到 image_viewer。 - 按钮样式切换为 ModernStylesheet(success/primary)统一视觉。
2026-06-17 13:28:58 +08:00
# 用 lambda 注入 step_id:finished/error 都拿得到自己服务的是哪一步
self.worker.finished.connect(
lambda result, sid=step_id: self._on_step_done(sid, result)
)
self.worker.error.connect(
lambda msg, sid=step_id: self._on_step_error(sid, msg)
)
self.worker.start()
def _load_callable(self, module_name: str, attr_name: str):
"""动态加载 ``module_name.attr_name``,失败时写日志并返回 None"""
try:
module = importlib.import_module(module_name)
return getattr(module, attr_name)
except Exception as e: # noqa: BLE001
self._log(f"[Router] 加载 service 失败 ({module_name}.{attr_name}): {e}")
traceback.print_exc()
return None
feat(new-arch):主窗口全功能增强(图标系统 + 全链路参数同步 + 服务输出统一解析 + Step12 分类浏览) 1. main_view.py:图标系统 + 全链路参数自动传导 - 新增 _res() 解析项目根的相对路径,PyInstaller 打包后兼容 sys._MEIPASS。 - 新增 QListWidgetItem / QMessageBox 导入,左侧导航列表支持右键菜单 + 错误弹窗。 - ROUTES 12 条全部新增 icon 字段("1.png" 等),侧边栏显示业务图标。 - 新增 step_outputs 缓存机制:每个 step 完成后把 output_path 写入 self.step_outputs。 - 新增 _sync_dependencies() 同步函数 + _safe_set_config() 包装器, 按依赖图把上游产物推给下游 view: step1 → step6 water_mask_path step3 → step4 / step6 / step10 deglint_img_path / bsq_path step4 → step9 sampling_csv_path step5 → step6 csv_path step6 → step7 / step8 training_csv_path step8 → step9 models_dir(父目录) step9 → step11 prediction_csv_dir / prediction_csv_path(双推) step10 → step11 geotiff_dir / geotiff_path(双推) 2. services/step1-13:统一输出解析器集成 - 新增 src/new/services/_output_resolver.py,提供 resolve_output_dir / copy_to_user_path / get_user_output_path / is_user_specified 四个共享工具。 - 每个 service 把原有的私有 _resolve_xxx_dir 改为调用 resolve_output_dir, 强制执行"用户优先"规则(用户指定 output_path 时用其父目录,否则用 work_dir/<subdir>)。 - 用户指定文件名 vs 底层硬编码文件名的"事后劫持"通过 copy_to_user_path 完成 (覆盖 step2、step4、step7、step8 等底层 step 不接受 output_path 关键字的步骤)。 3. views/step12_view.py:恢复 ImageCategoryTree + ImageViewerWidget 高级组件 - 删掉精简版占位 Label,挂回旧版的 ImageCategoryTree(按"模型评估/光谱分析/ 统计图表/处理结果/含量分布图"五类自动归类工作目录下的图像文件)。 - 挂回 ImageViewerWidget(滚轮缩放 0.1x-5x + 50ms 防抖 + FastTransformation/ SmoothTransformation 智能切换 + Ctrl+Wheel + 工具栏)。 - 扫描按钮接通 image_tree.scan_directory(),选中节点即时加载到 image_viewer。 - 按钮样式切换为 ModernStylesheet(success/primary)统一视觉。
2026-06-17 13:28:58 +08:00
def _on_step_done(self, step_id: str, result: dict):
"""TaskWorker finished 回调——按 status 分支写日志
feat(new-arch):主窗口全功能增强(图标系统 + 全链路参数同步 + 服务输出统一解析 + Step12 分类浏览) 1. main_view.py:图标系统 + 全链路参数自动传导 - 新增 _res() 解析项目根的相对路径,PyInstaller 打包后兼容 sys._MEIPASS。 - 新增 QListWidgetItem / QMessageBox 导入,左侧导航列表支持右键菜单 + 错误弹窗。 - ROUTES 12 条全部新增 icon 字段("1.png" 等),侧边栏显示业务图标。 - 新增 step_outputs 缓存机制:每个 step 完成后把 output_path 写入 self.step_outputs。 - 新增 _sync_dependencies() 同步函数 + _safe_set_config() 包装器, 按依赖图把上游产物推给下游 view: step1 → step6 water_mask_path step3 → step4 / step6 / step10 deglint_img_path / bsq_path step4 → step9 sampling_csv_path step5 → step6 csv_path step6 → step7 / step8 training_csv_path step8 → step9 models_dir(父目录) step9 → step11 prediction_csv_dir / prediction_csv_path(双推) step10 → step11 geotiff_dir / geotiff_path(双推) 2. services/step1-13:统一输出解析器集成 - 新增 src/new/services/_output_resolver.py,提供 resolve_output_dir / copy_to_user_path / get_user_output_path / is_user_specified 四个共享工具。 - 每个 service 把原有的私有 _resolve_xxx_dir 改为调用 resolve_output_dir, 强制执行"用户优先"规则(用户指定 output_path 时用其父目录,否则用 work_dir/<subdir>)。 - 用户指定文件名 vs 底层硬编码文件名的"事后劫持"通过 copy_to_user_path 完成 (覆盖 step2、step4、step7、step8 等底层 step 不接受 output_path 关键字的步骤)。 3. views/step12_view.py:恢复 ImageCategoryTree + ImageViewerWidget 高级组件 - 删掉精简版占位 Label,挂回旧版的 ImageCategoryTree(按"模型评估/光谱分析/ 统计图表/处理结果/含量分布图"五类自动归类工作目录下的图像文件)。 - 挂回 ImageViewerWidget(滚轮缩放 0.1x-5x + 50ms 防抖 + FastTransformation/ SmoothTransformation 智能切换 + Ctrl+Wheel + 工具栏)。 - 扫描按钮接通 image_tree.scan_directory(),选中节点即时加载到 image_viewer。 - 按钮样式切换为 ModernStylesheet(success/primary)统一视觉。
2026-06-17 13:28:58 +08:00
1. 缓存 output_path 到 self.step_outputs;
2. 触发 _sync_dependencies 把产出路径推给所有下游 view;
3. status=completed → QMessageBox.information;status=error → warning。
注:service 内部 try/except 转换的 status='error' 也走这里;
这与 error 信号(worker 自身崩溃)语义不同。
"""
status = result.get("status", "unknown")
message = result.get("message", "")
output_path = result.get("output_path")
mode = result.get("mode", "")
feat(new-arch):主窗口全功能增强(图标系统 + 全链路参数同步 + 服务输出统一解析 + Step12 分类浏览) 1. main_view.py:图标系统 + 全链路参数自动传导 - 新增 _res() 解析项目根的相对路径,PyInstaller 打包后兼容 sys._MEIPASS。 - 新增 QListWidgetItem / QMessageBox 导入,左侧导航列表支持右键菜单 + 错误弹窗。 - ROUTES 12 条全部新增 icon 字段("1.png" 等),侧边栏显示业务图标。 - 新增 step_outputs 缓存机制:每个 step 完成后把 output_path 写入 self.step_outputs。 - 新增 _sync_dependencies() 同步函数 + _safe_set_config() 包装器, 按依赖图把上游产物推给下游 view: step1 → step6 water_mask_path step3 → step4 / step6 / step10 deglint_img_path / bsq_path step4 → step9 sampling_csv_path step5 → step6 csv_path step6 → step7 / step8 training_csv_path step8 → step9 models_dir(父目录) step9 → step11 prediction_csv_dir / prediction_csv_path(双推) step10 → step11 geotiff_dir / geotiff_path(双推) 2. services/step1-13:统一输出解析器集成 - 新增 src/new/services/_output_resolver.py,提供 resolve_output_dir / copy_to_user_path / get_user_output_path / is_user_specified 四个共享工具。 - 每个 service 把原有的私有 _resolve_xxx_dir 改为调用 resolve_output_dir, 强制执行"用户优先"规则(用户指定 output_path 时用其父目录,否则用 work_dir/<subdir>)。 - 用户指定文件名 vs 底层硬编码文件名的"事后劫持"通过 copy_to_user_path 完成 (覆盖 step2、step4、step7、step8 等底层 step 不接受 output_path 关键字的步骤)。 3. views/step12_view.py:恢复 ImageCategoryTree + ImageViewerWidget 高级组件 - 删掉精简版占位 Label,挂回旧版的 ImageCategoryTree(按"模型评估/光谱分析/ 统计图表/处理结果/含量分布图"五类自动归类工作目录下的图像文件)。 - 挂回 ImageViewerWidget(滚轮缩放 0.1x-5x + 50ms 防抖 + FastTransformation/ SmoothTransformation 智能切换 + Ctrl+Wheel + 工具栏)。 - 扫描按钮接通 image_tree.scan_directory(),选中节点即时加载到 image_viewer。 - 按钮样式切换为 ModernStylesheet(success/primary)统一视觉。
2026-06-17 13:28:58 +08:00
# 1. 缓存路径 + 触发声明式下游推送(即使 error 也要缓存,让用户看到已失败)
if output_path:
self.step_outputs[step_id] = str(output_path)
self._log(f"[Cache] {step_id} → step_outputs['{step_id}'] = {output_path}")
self._sync_dependencies()
else:
self._log(f"[Cache] {step_id} 无 output_path,跳过 step_outputs 缓存")
# 2. 日志分支 + 弹窗提示
if status == "completed":
self._log(f"[Service✓] {message}(mode={mode}, output={output_path})")
feat(new-arch):主窗口全功能增强(图标系统 + 全链路参数同步 + 服务输出统一解析 + Step12 分类浏览) 1. main_view.py:图标系统 + 全链路参数自动传导 - 新增 _res() 解析项目根的相对路径,PyInstaller 打包后兼容 sys._MEIPASS。 - 新增 QListWidgetItem / QMessageBox 导入,左侧导航列表支持右键菜单 + 错误弹窗。 - ROUTES 12 条全部新增 icon 字段("1.png" 等),侧边栏显示业务图标。 - 新增 step_outputs 缓存机制:每个 step 完成后把 output_path 写入 self.step_outputs。 - 新增 _sync_dependencies() 同步函数 + _safe_set_config() 包装器, 按依赖图把上游产物推给下游 view: step1 → step6 water_mask_path step3 → step4 / step6 / step10 deglint_img_path / bsq_path step4 → step9 sampling_csv_path step5 → step6 csv_path step6 → step7 / step8 training_csv_path step8 → step9 models_dir(父目录) step9 → step11 prediction_csv_dir / prediction_csv_path(双推) step10 → step11 geotiff_dir / geotiff_path(双推) 2. services/step1-13:统一输出解析器集成 - 新增 src/new/services/_output_resolver.py,提供 resolve_output_dir / copy_to_user_path / get_user_output_path / is_user_specified 四个共享工具。 - 每个 service 把原有的私有 _resolve_xxx_dir 改为调用 resolve_output_dir, 强制执行"用户优先"规则(用户指定 output_path 时用其父目录,否则用 work_dir/<subdir>)。 - 用户指定文件名 vs 底层硬编码文件名的"事后劫持"通过 copy_to_user_path 完成 (覆盖 step2、step4、step7、step8 等底层 step 不接受 output_path 关键字的步骤)。 3. views/step12_view.py:恢复 ImageCategoryTree + ImageViewerWidget 高级组件 - 删掉精简版占位 Label,挂回旧版的 ImageCategoryTree(按"模型评估/光谱分析/ 统计图表/处理结果/含量分布图"五类自动归类工作目录下的图像文件)。 - 挂回 ImageViewerWidget(滚轮缩放 0.1x-5x + 50ms 防抖 + FastTransformation/ SmoothTransformation 智能切换 + Ctrl+Wheel + 工具栏)。 - 扫描按钮接通 image_tree.scan_directory(),选中节点即时加载到 image_viewer。 - 按钮样式切换为 ModernStylesheet(success/primary)统一视觉。
2026-06-17 13:28:58 +08:00
QMessageBox.information(
self,
"执行完成",
f"{message or '当前步骤已完成!'}\n\n产出路径:\n{output_path or '(无)'}",
)
elif status == "skipped":
self._log(f"[Service↻] {message}(已复用历史结果)")
elif status == "not_implemented":
self._log(f"[Service…] {message}")
else: # error(service 内部已转 dict)
self._log(f"[Service✗] {message}(mode={mode or 'n/a'})")
tb = result.get("traceback")
if tb:
self._log(tb)
feat(new-arch):主窗口全功能增强(图标系统 + 全链路参数同步 + 服务输出统一解析 + Step12 分类浏览) 1. main_view.py:图标系统 + 全链路参数自动传导 - 新增 _res() 解析项目根的相对路径,PyInstaller 打包后兼容 sys._MEIPASS。 - 新增 QListWidgetItem / QMessageBox 导入,左侧导航列表支持右键菜单 + 错误弹窗。 - ROUTES 12 条全部新增 icon 字段("1.png" 等),侧边栏显示业务图标。 - 新增 step_outputs 缓存机制:每个 step 完成后把 output_path 写入 self.step_outputs。 - 新增 _sync_dependencies() 同步函数 + _safe_set_config() 包装器, 按依赖图把上游产物推给下游 view: step1 → step6 water_mask_path step3 → step4 / step6 / step10 deglint_img_path / bsq_path step4 → step9 sampling_csv_path step5 → step6 csv_path step6 → step7 / step8 training_csv_path step8 → step9 models_dir(父目录) step9 → step11 prediction_csv_dir / prediction_csv_path(双推) step10 → step11 geotiff_dir / geotiff_path(双推) 2. services/step1-13:统一输出解析器集成 - 新增 src/new/services/_output_resolver.py,提供 resolve_output_dir / copy_to_user_path / get_user_output_path / is_user_specified 四个共享工具。 - 每个 service 把原有的私有 _resolve_xxx_dir 改为调用 resolve_output_dir, 强制执行"用户优先"规则(用户指定 output_path 时用其父目录,否则用 work_dir/<subdir>)。 - 用户指定文件名 vs 底层硬编码文件名的"事后劫持"通过 copy_to_user_path 完成 (覆盖 step2、step4、step7、step8 等底层 step 不接受 output_path 关键字的步骤)。 3. views/step12_view.py:恢复 ImageCategoryTree + ImageViewerWidget 高级组件 - 删掉精简版占位 Label,挂回旧版的 ImageCategoryTree(按"模型评估/光谱分析/ 统计图表/处理结果/含量分布图"五类自动归类工作目录下的图像文件)。 - 挂回 ImageViewerWidget(滚轮缩放 0.1x-5x + 50ms 防抖 + FastTransformation/ SmoothTransformation 智能切换 + Ctrl+Wheel + 工具栏)。 - 扫描按钮接通 image_tree.scan_directory(),选中节点即时加载到 image_viewer。 - 按钮样式切换为 ModernStylesheet(success/primary)统一视觉。
2026-06-17 13:28:58 +08:00
QMessageBox.warning(
self,
"执行失败",
f"{message or '当前步骤执行失败'}\n\n请查看底部日志获取 traceback。",
)
def _on_step_error(self, step_id: str, msg: str):
"""TaskWorker error 信号回调——worker 自身捕获的未预期异常
worker 自身崩溃(service_func 抛出未捕获异常)走这里;
与 finished 中 status='error' 语义不同:error 信号表示 worker
完全无法产出结果 dict。
"""
self._log(f"[Worker✗] {step_id} 未预期异常:\n{msg}")
QMessageBox.critical(
self,
"Worker 异常",
f"步骤 {step_id} 后台执行崩溃:\n\n{msg[:500]}",
)
feat(new-arch):主窗口全功能增强(图标系统 + 全链路参数同步 + 服务输出统一解析 + Step12 分类浏览) 1. main_view.py:图标系统 + 全链路参数自动传导 - 新增 _res() 解析项目根的相对路径,PyInstaller 打包后兼容 sys._MEIPASS。 - 新增 QListWidgetItem / QMessageBox 导入,左侧导航列表支持右键菜单 + 错误弹窗。 - ROUTES 12 条全部新增 icon 字段("1.png" 等),侧边栏显示业务图标。 - 新增 step_outputs 缓存机制:每个 step 完成后把 output_path 写入 self.step_outputs。 - 新增 _sync_dependencies() 同步函数 + _safe_set_config() 包装器, 按依赖图把上游产物推给下游 view: step1 → step6 water_mask_path step3 → step4 / step6 / step10 deglint_img_path / bsq_path step4 → step9 sampling_csv_path step5 → step6 csv_path step6 → step7 / step8 training_csv_path step8 → step9 models_dir(父目录) step9 → step11 prediction_csv_dir / prediction_csv_path(双推) step10 → step11 geotiff_dir / geotiff_path(双推) 2. services/step1-13:统一输出解析器集成 - 新增 src/new/services/_output_resolver.py,提供 resolve_output_dir / copy_to_user_path / get_user_output_path / is_user_specified 四个共享工具。 - 每个 service 把原有的私有 _resolve_xxx_dir 改为调用 resolve_output_dir, 强制执行"用户优先"规则(用户指定 output_path 时用其父目录,否则用 work_dir/<subdir>)。 - 用户指定文件名 vs 底层硬编码文件名的"事后劫持"通过 copy_to_user_path 完成 (覆盖 step2、step4、step7、step8 等底层 step 不接受 output_path 关键字的步骤)。 3. views/step12_view.py:恢复 ImageCategoryTree + ImageViewerWidget 高级组件 - 删掉精简版占位 Label,挂回旧版的 ImageCategoryTree(按"模型评估/光谱分析/ 统计图表/处理结果/含量分布图"五类自动归类工作目录下的图像文件)。 - 挂回 ImageViewerWidget(滚轮缩放 0.1x-5x + 50ms 防抖 + FastTransformation/ SmoothTransformation 智能切换 + Ctrl+Wheel + 工具栏)。 - 扫描按钮接通 image_tree.scan_directory(),选中节点即时加载到 image_viewer。 - 按钮样式切换为 ModernStylesheet(success/primary)统一视觉。
2026-06-17 13:28:58 +08:00
# ------------------------------------------------------------------
# 声明式路径流转:用 set_config 把上游产出推给所有下游 view
# ------------------------------------------------------------------
def _sync_dependencies(self):
"""遍历 self.step_outputs 字典,按依赖图把每步产出推给下游"""
# ----- step1 → step2/3/4 (water_mask_path) 及 step6 (boundary_path) -----
feat(new-arch):主窗口全功能增强(图标系统 + 全链路参数同步 + 服务输出统一解析 + Step12 分类浏览) 1. main_view.py:图标系统 + 全链路参数自动传导 - 新增 _res() 解析项目根的相对路径,PyInstaller 打包后兼容 sys._MEIPASS。 - 新增 QListWidgetItem / QMessageBox 导入,左侧导航列表支持右键菜单 + 错误弹窗。 - ROUTES 12 条全部新增 icon 字段("1.png" 等),侧边栏显示业务图标。 - 新增 step_outputs 缓存机制:每个 step 完成后把 output_path 写入 self.step_outputs。 - 新增 _sync_dependencies() 同步函数 + _safe_set_config() 包装器, 按依赖图把上游产物推给下游 view: step1 → step6 water_mask_path step3 → step4 / step6 / step10 deglint_img_path / bsq_path step4 → step9 sampling_csv_path step5 → step6 csv_path step6 → step7 / step8 training_csv_path step8 → step9 models_dir(父目录) step9 → step11 prediction_csv_dir / prediction_csv_path(双推) step10 → step11 geotiff_dir / geotiff_path(双推) 2. services/step1-13:统一输出解析器集成 - 新增 src/new/services/_output_resolver.py,提供 resolve_output_dir / copy_to_user_path / get_user_output_path / is_user_specified 四个共享工具。 - 每个 service 把原有的私有 _resolve_xxx_dir 改为调用 resolve_output_dir, 强制执行"用户优先"规则(用户指定 output_path 时用其父目录,否则用 work_dir/<subdir>)。 - 用户指定文件名 vs 底层硬编码文件名的"事后劫持"通过 copy_to_user_path 完成 (覆盖 step2、step4、step7、step8 等底层 step 不接受 output_path 关键字的步骤)。 3. views/step12_view.py:恢复 ImageCategoryTree + ImageViewerWidget 高级组件 - 删掉精简版占位 Label,挂回旧版的 ImageCategoryTree(按"模型评估/光谱分析/ 统计图表/处理结果/含量分布图"五类自动归类工作目录下的图像文件)。 - 挂回 ImageViewerWidget(滚轮缩放 0.1x-5x + 50ms 防抖 + FastTransformation/ SmoothTransformation 智能切换 + Ctrl+Wheel + 工具栏)。 - 扫描按钮接通 image_tree.scan_directory(),选中节点即时加载到 image_viewer。 - 按钮样式切换为 ModernStylesheet(success/primary)统一视觉。
2026-06-17 13:28:58 +08:00
s1 = self.step_outputs.get("step1")
if s1:
for sid in ("step2", "step3", "step4"):
self._safe_set_config(sid, {"water_mask_path": s1})
# 补齐 step1 到 step6 的水体掩膜链路
self._safe_set_config("step6", {"boundary_path": s1})
# ----- step2 → step6 (glint_mask_path) -----
s2 = self.step_outputs.get("step2")
if s2:
# 补齐 step2 到 step6 的耀斑掩膜链路
self._safe_set_config("step6", {"glint_mask_path": s2})
feat(new-arch):主窗口全功能增强(图标系统 + 全链路参数同步 + 服务输出统一解析 + Step12 分类浏览) 1. main_view.py:图标系统 + 全链路参数自动传导 - 新增 _res() 解析项目根的相对路径,PyInstaller 打包后兼容 sys._MEIPASS。 - 新增 QListWidgetItem / QMessageBox 导入,左侧导航列表支持右键菜单 + 错误弹窗。 - ROUTES 12 条全部新增 icon 字段("1.png" 等),侧边栏显示业务图标。 - 新增 step_outputs 缓存机制:每个 step 完成后把 output_path 写入 self.step_outputs。 - 新增 _sync_dependencies() 同步函数 + _safe_set_config() 包装器, 按依赖图把上游产物推给下游 view: step1 → step6 water_mask_path step3 → step4 / step6 / step10 deglint_img_path / bsq_path step4 → step9 sampling_csv_path step5 → step6 csv_path step6 → step7 / step8 training_csv_path step8 → step9 models_dir(父目录) step9 → step11 prediction_csv_dir / prediction_csv_path(双推) step10 → step11 geotiff_dir / geotiff_path(双推) 2. services/step1-13:统一输出解析器集成 - 新增 src/new/services/_output_resolver.py,提供 resolve_output_dir / copy_to_user_path / get_user_output_path / is_user_specified 四个共享工具。 - 每个 service 把原有的私有 _resolve_xxx_dir 改为调用 resolve_output_dir, 强制执行"用户优先"规则(用户指定 output_path 时用其父目录,否则用 work_dir/<subdir>)。 - 用户指定文件名 vs 底层硬编码文件名的"事后劫持"通过 copy_to_user_path 完成 (覆盖 step2、step4、step7、step8 等底层 step 不接受 output_path 关键字的步骤)。 3. views/step12_view.py:恢复 ImageCategoryTree + ImageViewerWidget 高级组件 - 删掉精简版占位 Label,挂回旧版的 ImageCategoryTree(按"模型评估/光谱分析/ 统计图表/处理结果/含量分布图"五类自动归类工作目录下的图像文件)。 - 挂回 ImageViewerWidget(滚轮缩放 0.1x-5x + 50ms 防抖 + FastTransformation/ SmoothTransformation 智能切换 + Ctrl+Wheel + 工具栏)。 - 扫描按钮接通 image_tree.scan_directory(),选中节点即时加载到 image_viewer。 - 按钮样式切换为 ModernStylesheet(success/primary)统一视觉。
2026-06-17 13:28:58 +08:00
# ----- step3 → step4/6 (deglint_img_path) / step10 (bsq_path) -----
feat(new-arch):主窗口全功能增强(图标系统 + 全链路参数同步 + 服务输出统一解析 + Step12 分类浏览) 1. main_view.py:图标系统 + 全链路参数自动传导 - 新增 _res() 解析项目根的相对路径,PyInstaller 打包后兼容 sys._MEIPASS。 - 新增 QListWidgetItem / QMessageBox 导入,左侧导航列表支持右键菜单 + 错误弹窗。 - ROUTES 12 条全部新增 icon 字段("1.png" 等),侧边栏显示业务图标。 - 新增 step_outputs 缓存机制:每个 step 完成后把 output_path 写入 self.step_outputs。 - 新增 _sync_dependencies() 同步函数 + _safe_set_config() 包装器, 按依赖图把上游产物推给下游 view: step1 → step6 water_mask_path step3 → step4 / step6 / step10 deglint_img_path / bsq_path step4 → step9 sampling_csv_path step5 → step6 csv_path step6 → step7 / step8 training_csv_path step8 → step9 models_dir(父目录) step9 → step11 prediction_csv_dir / prediction_csv_path(双推) step10 → step11 geotiff_dir / geotiff_path(双推) 2. services/step1-13:统一输出解析器集成 - 新增 src/new/services/_output_resolver.py,提供 resolve_output_dir / copy_to_user_path / get_user_output_path / is_user_specified 四个共享工具。 - 每个 service 把原有的私有 _resolve_xxx_dir 改为调用 resolve_output_dir, 强制执行"用户优先"规则(用户指定 output_path 时用其父目录,否则用 work_dir/<subdir>)。 - 用户指定文件名 vs 底层硬编码文件名的"事后劫持"通过 copy_to_user_path 完成 (覆盖 step2、step4、step7、step8 等底层 step 不接受 output_path 关键字的步骤)。 3. views/step12_view.py:恢复 ImageCategoryTree + ImageViewerWidget 高级组件 - 删掉精简版占位 Label,挂回旧版的 ImageCategoryTree(按"模型评估/光谱分析/ 统计图表/处理结果/含量分布图"五类自动归类工作目录下的图像文件)。 - 挂回 ImageViewerWidget(滚轮缩放 0.1x-5x + 50ms 防抖 + FastTransformation/ SmoothTransformation 智能切换 + Ctrl+Wheel + 工具栏)。 - 扫描按钮接通 image_tree.scan_directory(),选中节点即时加载到 image_viewer。 - 按钮样式切换为 ModernStylesheet(success/primary)统一视觉。
2026-06-17 13:28:58 +08:00
s3 = self.step_outputs.get("step3")
if s3:
self._safe_set_config("step4", {"deglint_img_path": s3})
self._safe_set_config("step6", {"deglint_img_path": s3})
self._safe_set_config("step10", {"bsq_path": s3})
# ----- step4 → step9 (sampling_csv_path) -----
feat(new-arch):主窗口全功能增强(图标系统 + 全链路参数同步 + 服务输出统一解析 + Step12 分类浏览) 1. main_view.py:图标系统 + 全链路参数自动传导 - 新增 _res() 解析项目根的相对路径,PyInstaller 打包后兼容 sys._MEIPASS。 - 新增 QListWidgetItem / QMessageBox 导入,左侧导航列表支持右键菜单 + 错误弹窗。 - ROUTES 12 条全部新增 icon 字段("1.png" 等),侧边栏显示业务图标。 - 新增 step_outputs 缓存机制:每个 step 完成后把 output_path 写入 self.step_outputs。 - 新增 _sync_dependencies() 同步函数 + _safe_set_config() 包装器, 按依赖图把上游产物推给下游 view: step1 → step6 water_mask_path step3 → step4 / step6 / step10 deglint_img_path / bsq_path step4 → step9 sampling_csv_path step5 → step6 csv_path step6 → step7 / step8 training_csv_path step8 → step9 models_dir(父目录) step9 → step11 prediction_csv_dir / prediction_csv_path(双推) step10 → step11 geotiff_dir / geotiff_path(双推) 2. services/step1-13:统一输出解析器集成 - 新增 src/new/services/_output_resolver.py,提供 resolve_output_dir / copy_to_user_path / get_user_output_path / is_user_specified 四个共享工具。 - 每个 service 把原有的私有 _resolve_xxx_dir 改为调用 resolve_output_dir, 强制执行"用户优先"规则(用户指定 output_path 时用其父目录,否则用 work_dir/<subdir>)。 - 用户指定文件名 vs 底层硬编码文件名的"事后劫持"通过 copy_to_user_path 完成 (覆盖 step2、step4、step7、step8 等底层 step 不接受 output_path 关键字的步骤)。 3. views/step12_view.py:恢复 ImageCategoryTree + ImageViewerWidget 高级组件 - 删掉精简版占位 Label,挂回旧版的 ImageCategoryTree(按"模型评估/光谱分析/ 统计图表/处理结果/含量分布图"五类自动归类工作目录下的图像文件)。 - 挂回 ImageViewerWidget(滚轮缩放 0.1x-5x + 50ms 防抖 + FastTransformation/ SmoothTransformation 智能切换 + Ctrl+Wheel + 工具栏)。 - 扫描按钮接通 image_tree.scan_directory(),选中节点即时加载到 image_viewer。 - 按钮样式切换为 ModernStylesheet(success/primary)统一视觉。
2026-06-17 13:28:58 +08:00
s4 = self.step_outputs.get("step4")
if s4:
self._safe_set_config("step9", {"sampling_csv_path": s4})
# ----- step5 → step6 (csv_path) -----
s5 = self.step_outputs.get("step5")
if s5:
self._safe_set_config("step6", {"csv_path": s5})
# ----- step6 → step7/step8 (training_csv_path) -----
s6 = self.step_outputs.get("step6")
if s6:
self._safe_set_config("step7", {"training_csv_path": s6})
self._safe_set_config("step8", {"training_csv_path": s6})
# ----- step8 → step9 (models_dir: 父目录) -----
feat(new-arch):主窗口全功能增强(图标系统 + 全链路参数同步 + 服务输出统一解析 + Step12 分类浏览) 1. main_view.py:图标系统 + 全链路参数自动传导 - 新增 _res() 解析项目根的相对路径,PyInstaller 打包后兼容 sys._MEIPASS。 - 新增 QListWidgetItem / QMessageBox 导入,左侧导航列表支持右键菜单 + 错误弹窗。 - ROUTES 12 条全部新增 icon 字段("1.png" 等),侧边栏显示业务图标。 - 新增 step_outputs 缓存机制:每个 step 完成后把 output_path 写入 self.step_outputs。 - 新增 _sync_dependencies() 同步函数 + _safe_set_config() 包装器, 按依赖图把上游产物推给下游 view: step1 → step6 water_mask_path step3 → step4 / step6 / step10 deglint_img_path / bsq_path step4 → step9 sampling_csv_path step5 → step6 csv_path step6 → step7 / step8 training_csv_path step8 → step9 models_dir(父目录) step9 → step11 prediction_csv_dir / prediction_csv_path(双推) step10 → step11 geotiff_dir / geotiff_path(双推) 2. services/step1-13:统一输出解析器集成 - 新增 src/new/services/_output_resolver.py,提供 resolve_output_dir / copy_to_user_path / get_user_output_path / is_user_specified 四个共享工具。 - 每个 service 把原有的私有 _resolve_xxx_dir 改为调用 resolve_output_dir, 强制执行"用户优先"规则(用户指定 output_path 时用其父目录,否则用 work_dir/<subdir>)。 - 用户指定文件名 vs 底层硬编码文件名的"事后劫持"通过 copy_to_user_path 完成 (覆盖 step2、step4、step7、step8 等底层 step 不接受 output_path 关键字的步骤)。 3. views/step12_view.py:恢复 ImageCategoryTree + ImageViewerWidget 高级组件 - 删掉精简版占位 Label,挂回旧版的 ImageCategoryTree(按"模型评估/光谱分析/ 统计图表/处理结果/含量分布图"五类自动归类工作目录下的图像文件)。 - 挂回 ImageViewerWidget(滚轮缩放 0.1x-5x + 50ms 防抖 + FastTransformation/ SmoothTransformation 智能切换 + Ctrl+Wheel + 工具栏)。 - 扫描按钮接通 image_tree.scan_directory(),选中节点即时加载到 image_viewer。 - 按钮样式切换为 ModernStylesheet(success/primary)统一视觉。
2026-06-17 13:28:58 +08:00
s8 = self.step_outputs.get("step8")
if s8:
s8_dir = str(Path(s8).parent).replace("\\", "/")
self._safe_set_config("step9", {"models_dir": s8_dir})
# ----- step9 → step11 (prediction_csv_dir / prediction_csv_path) -----
feat(new-arch):主窗口全功能增强(图标系统 + 全链路参数同步 + 服务输出统一解析 + Step12 分类浏览) 1. main_view.py:图标系统 + 全链路参数自动传导 - 新增 _res() 解析项目根的相对路径,PyInstaller 打包后兼容 sys._MEIPASS。 - 新增 QListWidgetItem / QMessageBox 导入,左侧导航列表支持右键菜单 + 错误弹窗。 - ROUTES 12 条全部新增 icon 字段("1.png" 等),侧边栏显示业务图标。 - 新增 step_outputs 缓存机制:每个 step 完成后把 output_path 写入 self.step_outputs。 - 新增 _sync_dependencies() 同步函数 + _safe_set_config() 包装器, 按依赖图把上游产物推给下游 view: step1 → step6 water_mask_path step3 → step4 / step6 / step10 deglint_img_path / bsq_path step4 → step9 sampling_csv_path step5 → step6 csv_path step6 → step7 / step8 training_csv_path step8 → step9 models_dir(父目录) step9 → step11 prediction_csv_dir / prediction_csv_path(双推) step10 → step11 geotiff_dir / geotiff_path(双推) 2. services/step1-13:统一输出解析器集成 - 新增 src/new/services/_output_resolver.py,提供 resolve_output_dir / copy_to_user_path / get_user_output_path / is_user_specified 四个共享工具。 - 每个 service 把原有的私有 _resolve_xxx_dir 改为调用 resolve_output_dir, 强制执行"用户优先"规则(用户指定 output_path 时用其父目录,否则用 work_dir/<subdir>)。 - 用户指定文件名 vs 底层硬编码文件名的"事后劫持"通过 copy_to_user_path 完成 (覆盖 step2、step4、step7、step8 等底层 step 不接受 output_path 关键字的步骤)。 3. views/step12_view.py:恢复 ImageCategoryTree + ImageViewerWidget 高级组件 - 删掉精简版占位 Label,挂回旧版的 ImageCategoryTree(按"模型评估/光谱分析/ 统计图表/处理结果/含量分布图"五类自动归类工作目录下的图像文件)。 - 挂回 ImageViewerWidget(滚轮缩放 0.1x-5x + 50ms 防抖 + FastTransformation/ SmoothTransformation 智能切换 + Ctrl+Wheel + 工具栏)。 - 扫描按钮接通 image_tree.scan_directory(),选中节点即时加载到 image_viewer。 - 按钮样式切换为 ModernStylesheet(success/primary)统一视觉。
2026-06-17 13:28:58 +08:00
s9 = self.step_outputs.get("step9")
if s9:
s9_dir = str(Path(s9).parent).replace("\\", "/")
self._safe_set_config("step11", {"prediction_csv_dir": s9_dir})
self._safe_set_config("step11", {"prediction_csv_path": s9})
# ----- step10 → step11 (geotiff_dir / geotiff_path) -----
feat(new-arch):主窗口全功能增强(图标系统 + 全链路参数同步 + 服务输出统一解析 + Step12 分类浏览) 1. main_view.py:图标系统 + 全链路参数自动传导 - 新增 _res() 解析项目根的相对路径,PyInstaller 打包后兼容 sys._MEIPASS。 - 新增 QListWidgetItem / QMessageBox 导入,左侧导航列表支持右键菜单 + 错误弹窗。 - ROUTES 12 条全部新增 icon 字段("1.png" 等),侧边栏显示业务图标。 - 新增 step_outputs 缓存机制:每个 step 完成后把 output_path 写入 self.step_outputs。 - 新增 _sync_dependencies() 同步函数 + _safe_set_config() 包装器, 按依赖图把上游产物推给下游 view: step1 → step6 water_mask_path step3 → step4 / step6 / step10 deglint_img_path / bsq_path step4 → step9 sampling_csv_path step5 → step6 csv_path step6 → step7 / step8 training_csv_path step8 → step9 models_dir(父目录) step9 → step11 prediction_csv_dir / prediction_csv_path(双推) step10 → step11 geotiff_dir / geotiff_path(双推) 2. services/step1-13:统一输出解析器集成 - 新增 src/new/services/_output_resolver.py,提供 resolve_output_dir / copy_to_user_path / get_user_output_path / is_user_specified 四个共享工具。 - 每个 service 把原有的私有 _resolve_xxx_dir 改为调用 resolve_output_dir, 强制执行"用户优先"规则(用户指定 output_path 时用其父目录,否则用 work_dir/<subdir>)。 - 用户指定文件名 vs 底层硬编码文件名的"事后劫持"通过 copy_to_user_path 完成 (覆盖 step2、step4、step7、step8 等底层 step 不接受 output_path 关键字的步骤)。 3. views/step12_view.py:恢复 ImageCategoryTree + ImageViewerWidget 高级组件 - 删掉精简版占位 Label,挂回旧版的 ImageCategoryTree(按"模型评估/光谱分析/ 统计图表/处理结果/含量分布图"五类自动归类工作目录下的图像文件)。 - 挂回 ImageViewerWidget(滚轮缩放 0.1x-5x + 50ms 防抖 + FastTransformation/ SmoothTransformation 智能切换 + Ctrl+Wheel + 工具栏)。 - 扫描按钮接通 image_tree.scan_directory(),选中节点即时加载到 image_viewer。 - 按钮样式切换为 ModernStylesheet(success/primary)统一视觉。
2026-06-17 13:28:58 +08:00
s10 = self.step_outputs.get("step10")
if s10:
s10_dir = str(Path(s10).parent).replace("\\", "/")
self._safe_set_config("step11", {"geotiff_dir": s10_dir})
self._safe_set_config("step11", {"geotiff_path": s10})
self._log(f"[Sync] 全局依赖同步完成(step_outputs keys: {list(self.step_outputs.keys())})")
feat(new-arch):主窗口全功能增强(图标系统 + 全链路参数同步 + 服务输出统一解析 + Step12 分类浏览) 1. main_view.py:图标系统 + 全链路参数自动传导 - 新增 _res() 解析项目根的相对路径,PyInstaller 打包后兼容 sys._MEIPASS。 - 新增 QListWidgetItem / QMessageBox 导入,左侧导航列表支持右键菜单 + 错误弹窗。 - ROUTES 12 条全部新增 icon 字段("1.png" 等),侧边栏显示业务图标。 - 新增 step_outputs 缓存机制:每个 step 完成后把 output_path 写入 self.step_outputs。 - 新增 _sync_dependencies() 同步函数 + _safe_set_config() 包装器, 按依赖图把上游产物推给下游 view: step1 → step6 water_mask_path step3 → step4 / step6 / step10 deglint_img_path / bsq_path step4 → step9 sampling_csv_path step5 → step6 csv_path step6 → step7 / step8 training_csv_path step8 → step9 models_dir(父目录) step9 → step11 prediction_csv_dir / prediction_csv_path(双推) step10 → step11 geotiff_dir / geotiff_path(双推) 2. services/step1-13:统一输出解析器集成 - 新增 src/new/services/_output_resolver.py,提供 resolve_output_dir / copy_to_user_path / get_user_output_path / is_user_specified 四个共享工具。 - 每个 service 把原有的私有 _resolve_xxx_dir 改为调用 resolve_output_dir, 强制执行"用户优先"规则(用户指定 output_path 时用其父目录,否则用 work_dir/<subdir>)。 - 用户指定文件名 vs 底层硬编码文件名的"事后劫持"通过 copy_to_user_path 完成 (覆盖 step2、step4、step7、step8 等底层 step 不接受 output_path 关键字的步骤)。 3. views/step12_view.py:恢复 ImageCategoryTree + ImageViewerWidget 高级组件 - 删掉精简版占位 Label,挂回旧版的 ImageCategoryTree(按"模型评估/光谱分析/ 统计图表/处理结果/含量分布图"五类自动归类工作目录下的图像文件)。 - 挂回 ImageViewerWidget(滚轮缩放 0.1x-5x + 50ms 防抖 + FastTransformation/ SmoothTransformation 智能切换 + Ctrl+Wheel + 工具栏)。 - 扫描按钮接通 image_tree.scan_directory(),选中节点即时加载到 image_viewer。 - 按钮样式切换为 ModernStylesheet(success/primary)统一视觉。
2026-06-17 13:28:58 +08:00
def _safe_set_config(self, step_id: str, config: dict):
"""安全调用 view.set_config;view 缺失 / 无该方法 / 抛异常时降级日志
返回 True 表示推送成功,False 表示降级跳过,便于上层做计数。
"""
view = self._views.get(step_id)
if view is None:
return False
if not hasattr(view, "set_config"):
self._log(f"[Sync] {step_id} 没有 set_config,跳过推送 {list(config.keys())}")
return False
try:
view.set_config(config)
self._log(f"[Sync] → {step_id}.set_config({config})")
return True
except Exception as e: # noqa: BLE001 —— 单步推送失败不影响整体 sync
self._log(f"[Sync] 推送 {step_id} 失败: {e}")
traceback.print_exc()
return False
# ------------------------------------------------------------------
# 全局输入参数广播:用户在一处导图 → 所有 view 自动同步
# ------------------------------------------------------------------
def _broadcast_global_inputs(self, config_dict: dict):
"""把本次 config_dict 中的公共输入 key 累计到 self.global_inputs,
再把整个 global_inputs 推给所有 view(实现"一处导入,全局共享")。
设计要点:
1. **非空才覆盖**——空字符串/None 不会污染已存在的有效值(防止下游
view 用空串覆盖掉上游刚刚推送的有效路径)。
2. **全量广播是安全的**——各 view.set_config 已实现 "if key in config"
守卫,未识别的 key 直接忽略,互不干扰。
3. **顺序无关**——多次 run_single_step 都会持续累计 self.global_inputs,
直到用户主动切换工作目录或清理。
"""
updated_keys: list[str] = []
for key in GLOBAL_INPUT_KEYS:
val = config_dict.get(key)
if val: # 非空才覆盖(None / "" 一律跳过)
self.global_inputs[key] = val
updated_keys.append(key)
if updated_keys:
self._log(
f"[Global] 本次更新 {len(updated_keys)} 个全局输入: {updated_keys}"
)
# 推送给所有 view
if not self._views:
return
n_ok, n_fail = 0, 0
for step_id, view in self._views.items():
if not hasattr(view, "set_config"):
continue
try:
view.set_config(self.global_inputs)
n_ok += 1
except Exception as e: # noqa: BLE001 —— 单 view 失败不影响其它
n_fail += 1
self._log(f"[Global] {step_id} 推送失败: {e}")
self._log(
f"[Global] 广播完成: ok={n_ok} fail={n_fail} "
f"keys={list(self.global_inputs.keys())}"
)
def clear_global_inputs(self):
"""清空全局输入缓存(工作目录切换 / 用户重置时调用)"""
self.global_inputs.clear()
self._log("[Global] 已清空全局输入缓存")
# ------------------------------------------------------------------
# 日志:所有日志统一走这里
# ------------------------------------------------------------------
def _log(self, msg: str):
# 控制台 + 底部日志框
print(msg)
self.log_text.append(msg)
# =========================================================================
# 入口
# =========================================================================
def main():
from PyQt5.QtWidgets import QApplication
app = QApplication(sys.argv)
win = MainView()
win.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()