From c5a82ec342ae40a35042e4617dee781d975d54a0 Mon Sep 17 00:00:00 2001 From: DXC Date: Tue, 23 Jun 2026 16:50:30 +0800 Subject: [PATCH] =?UTF-8?q?refactor(gui/sidebar):=20=E9=87=8D=E7=BB=84?= =?UTF-8?q?=E5=AF=BC=E8=88=AA=E4=B8=BA=E5=9B=9B=E6=A8=A1=E5=9D=97=20+=20?= =?UTF-8?q?=E6=89=81=E5=B9=B3=E6=97=A0=E6=A1=86=E8=93=9D=E8=89=B2=E9=AB=98?= =?UTF-8?q?=E4=BA=AE=E4=B8=BB=E9=A2=98=20+=20=E4=B8=AD=E6=8B=AC=E5=8F=B7?= =?UTF-8?q?=E7=A7=BB=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 数据层(panel_registry.py):13 个 step 从「阶段一/二/三/四」重组为四个模块 模块一 影像预处理(step 1-3) 模块二 特征工程与数据(step 4-7) 模块三 模型训练与反演(step 8-10) 模块四 制图与成果汇编(step 11-13) step_id 顺序、tab_index、面板绑定、Tab 路由全部保持零变化 文本层(water_quality_gui.py / v2):移除 └─ 字符前缀 样式层(styles.py:get_sidebar_stylesheet):扁平无框 + 蓝色高亮主题 - 容器 QListWidget 无框化(border: none / outline: none / 透明背景) - 步骤项 padding 8px 6px + margin 2px 8px + border-radius 4px - hover 极浅蓝灰 #F0F4F8;selected 饱和蓝 #0078D4 + 白字 #FFFFFF - 分类头(stage_header):!enabled 选择器锁定 → 蓝色 #0078D4 + 加粗 + 上下间距 Python 代码侧:stage_item.setForeground 硬编码 #0078D4、stage_font.setBold(True) 作为 QSS 失效兜底 + 代码意图自解释 末尾迭代:四个模块名移除 [ ] 中括号(极简风) --- src/gui/core/panel_registry.py | 34 ++++++++--------- src/gui/styles.py | 68 +++++++++++++++++++++++++-------- src/gui/water_quality_gui.py | 5 ++- src/gui/water_quality_gui_v2.py | 5 ++- 4 files changed, 76 insertions(+), 36 deletions(-) diff --git a/src/gui/core/panel_registry.py b/src/gui/core/panel_registry.py index 7308f8d..66c01cb 100644 --- a/src/gui/core/panel_registry.py +++ b/src/gui/core/panel_registry.py @@ -29,14 +29,14 @@ from src.gui.panels.step13_report_panel import Step13ReportPanel PANEL_REGISTRY = [ # ═══════════════════════════════════════════════════════════════ - # 阶段一:影像预处理 + # 模块一 影像预处理 # ═══════════════════════════════════════════════════════════════ { 'step_id': 'step1', 'class_ref': Step1Panel, 'title': '水域掩膜', 'icon': '1.png', - 'stage': '阶段一:影像预处理', + 'stage': '模块一 影像预处理', 'display_name': '1. 水域掩膜生成', 'dependencies': None, 'constructor_kwargs': None, @@ -46,7 +46,7 @@ PANEL_REGISTRY = [ 'class_ref': Step2Panel, 'title': '耀斑检测', 'icon': '2.png', - 'stage': '阶段一:影像预处理', + 'stage': '模块一 影像预处理', 'display_name': '2. 耀斑区域识别', # 架构解耦(2026-06-22):dict 键名 = 下游目标控件真实属性名; # 第三元素 source_attr = 上游源控件真实属性名(panel_factory 回放端使用) @@ -63,7 +63,7 @@ PANEL_REGISTRY = [ 'class_ref': Step3Panel, 'title': '耀斑去除', 'icon': '3.png', - 'stage': '阶段一:影像预处理', + 'stage': '模块一 影像预处理', 'display_name': '3. 耀斑去除与修复', # 架构解耦(2026-06-22):dict 键名 = 下游目标控件真实属性名 'dependencies': { @@ -76,14 +76,14 @@ PANEL_REGISTRY = [ }, # ═══════════════════════════════════════════════════════════════ - # 阶段二:样本数据准备 + # 模块二 特征工程与数据 # ═══════════════════════════════════════════════════════════════ { 'step_id': 'step4_sampling', 'class_ref': Step4SamplingPanel, 'title': '采样点布设', 'icon': '4.png', - 'stage': '阶段二:样本数据准备', + 'stage': '模块二 特征工程与数据', 'display_name': '4. 采样点布设', # 架构解耦(2026-06-22):dict 键名 = 下游目标控件真实属性名; # 第三元素 source_attr = 上游源控件真实属性名(panel_factory 回放端使用) @@ -100,7 +100,7 @@ PANEL_REGISTRY = [ 'class_ref': Step5CleanPanel, 'title': '数据清洗', 'icon': '5.png', - 'stage': '阶段二:样本数据准备', + 'stage': '模块二 特征工程与数据', 'display_name': '5. 数据清洗', # 业务要求保持输入源独立,不自动抓取 step4_sampling 的输出 'dependencies': None, @@ -111,7 +111,7 @@ PANEL_REGISTRY = [ 'class_ref': Step6FeaturePanel, 'title': '光谱特征', 'icon': '6.png', - 'stage': '阶段二:样本数据准备', + 'stage': '模块二 特征工程与数据', 'display_name': '6. 光谱特征提取', # 架构解耦(2026-06-22):dict 键名 = 下游目标控件真实属性名 'dependencies': { @@ -131,7 +131,7 @@ PANEL_REGISTRY = [ 'class_ref': Step7View, 'title': '水质光谱指数计算', 'icon': '7.png', - 'stage': '阶段二:样本数据准备', + 'stage': '模块二 特征工程与数据', 'display_name': '7. 水质指数计算', # 架构解耦(2026-06-22):dict 键名 = 下游目标控件真实属性名; # 第三元素 source_attr = 上游源控件真实属性名 @@ -143,14 +143,14 @@ PANEL_REGISTRY = [ }, # ═══════════════════════════════════════════════════════════════ - # 阶段三:模型构建与训练 + # 模块三 模型训练与反演 # ═══════════════════════════════════════════════════════════════ { 'step_id': 'step8_ml_train', 'class_ref': Step8MlTrainPanel, 'title': '机器学习建模', 'icon': '8.png', - 'stage': '阶段三:模型构建与训练', + 'stage': '模块三 模型训练与反演', 'display_name': '8. 机器学习建模', # 架构解耦(2026-06-22):dict 键名 = 下游目标控件真实属性名 'dependencies': { @@ -161,14 +161,14 @@ PANEL_REGISTRY = [ }, # ═══════════════════════════════════════════════════════════════ - # 阶段四:预测与成果输出 + # 模块三 模型训练与反演(续)→ 模块四 制图与成果汇编 # ═══════════════════════════════════════════════════════════════ { 'step_id': 'step9_ml_predict', 'class_ref': Step9MlPredictPanel, 'title': '机器学习预测', 'icon': '10.png', - 'stage': '阶段四:预测与成果输出', + 'stage': '模块三 模型训练与反演', 'display_name': '9. 机器学习预测', # 架构解耦(2026-06-22):dict 键名 = 下游目标控件真实属性名; # 第三元素 source_attr = 上游源控件真实属性名 @@ -183,7 +183,7 @@ PANEL_REGISTRY = [ 'class_ref': Step10WatercolorPanel, 'title': '水色指数反演', 'icon': '10.png', - 'stage': '阶段四:预测与成果输出', + 'stage': '模块三 模型训练与反演', 'display_name': '10. 水色指数反演', # 架构解耦(2026-06-22):dict 键名 = 下游目标控件真实属性名; # 第三元素 source_attr = 上游源控件真实属性名 @@ -200,7 +200,7 @@ PANEL_REGISTRY = [ 'class_ref': Step11MapPanel, 'title': '专题图生成', 'icon': '10.png', - 'stage': '阶段四:预测与成果输出', + 'stage': '模块四 制图与成果汇编', 'display_name': '11. 专题图生成', # 架构解耦(2026-06-22):dict 键名 = 下游目标控件真实属性名 'dependencies': { @@ -218,7 +218,7 @@ PANEL_REGISTRY = [ 'class_ref': Step12VizPanel, 'title': '可视化', 'icon': '9.png', - 'stage': '阶段四:预测与成果输出', + 'stage': '模块四 制图与成果汇编', 'display_name': '12. 可视化展示', 'dependencies': None, 'constructor_kwargs': None, @@ -228,7 +228,7 @@ PANEL_REGISTRY = [ 'class_ref': Step13ReportPanel, 'title': '报告生成', 'icon': '10.png', - 'stage': '阶段四:预测与成果输出', + 'stage': '模块四 制图与成果汇编', 'display_name': '13. 分析报告生成', 'dependencies': None, 'constructor_kwargs': {'main_window'}, # 需要注入 main_window=self diff --git a/src/gui/styles.py b/src/gui/styles.py index 7c8128b..6725536 100644 --- a/src/gui/styles.py +++ b/src/gui/styles.py @@ -538,8 +538,21 @@ class ModernStylesheet: @staticmethod def get_sidebar_stylesheet(): - """获取左侧边栏样式表""" + """获取左侧边栏样式表 + + 设计主题:扁平无框 + 蓝色高亮。 + 结构契约: + - 分类头 stage_header 项已通过 setFlags(~Qt.ItemIsEnabled) 禁用, + 因此 :!enabled 选择器可精确锁定分类头(蓝色加粗)。 + - 可点击的步骤项保持 enabled,进入 :enabled 通道 + (padding/margin 留白 + 圆角 + hover/selected 蓝色现代感)。 + """ colors = ModernStylesheet.COLORS + # 主题色板(蓝色高亮) + stage_header_color = '#0078D4' # 分类头:亮蓝色加粗 + step_hover_bg = '#F0F4F8' # hover(极浅蓝灰) + step_selected_bg = '#0078D4' # selected(饱和蓝) + step_selected_fg = '#FFFFFF' # selected(白字) return f""" QWidget {{ background-color: {colors['panel_bg']}; @@ -549,22 +562,47 @@ class ModernStylesheet: color: {colors['text_primary']}; font-weight: bold; }} + /* ── 容器:无框化、零描边、零焦点环 ── */ QListWidget {{ - background-color: {colors['panel_bg']}; - border: 0px; - border-right: 1px solid {colors['border_light']}; - }} - QListWidget::item {{ - padding: 8px; - border-left: 3px solid transparent; - }} - QListWidget::item:hover {{ - background-color: {colors['hover']}; - }} - QListWidget::item:selected {{ + border: none; + outline: none; background-color: transparent; - color: {colors['accent']}; - border-left: 3px solid {colors['accent']}; + }} + /* ── 分类头(stage_header,禁用态):亮蓝色 + 加粗 + 上下间距 ── */ + QListWidget::item:!enabled {{ + color: {stage_header_color}; + font-weight: bold; + background-color: transparent; + border: none; + padding: 14px 8px 6px 8px; + margin-top: 4px; + }} + /* ── 步骤项(enabled):padding/margin 留白 + 圆角过渡 ── */ + QListWidget::item:enabled {{ + color: {colors['text_secondary']}; + padding: 8px 6px; + margin: 2px 8px; + border: none; + border-radius: 4px; + }} + /* ── 步骤项 hover(未选中态):极浅蓝灰悬浮 ── */ + QListWidget::item:enabled:hover:!selected {{ + background-color: {step_hover_bg}; + color: {colors['text_primary']}; + }} + /* ── 步骤项 selected:饱和蓝高亮 + 白字 ── */ + QListWidget::item:enabled:selected {{ + background-color: {step_selected_bg}; + color: {step_selected_fg}; + border: none; font-weight: bold; }} + /* ── 分隔符占位项:完全透明,零干扰 ── */ + QListWidget::item[separator="true"] {{ + background-color: transparent; + border: none; + padding: 0px; + margin: 0px; + min-height: 4px; + }} """ diff --git a/src/gui/water_quality_gui.py b/src/gui/water_quality_gui.py index 8cb639f..a9f5ab7 100644 --- a/src/gui/water_quality_gui.py +++ b/src/gui/water_quality_gui.py @@ -578,8 +578,9 @@ class WaterQualityGUI(QMainWindow): # 添加阶段标题项(可视化分组) stage_item = QListWidgetItem(stage_name) stage_font = QFont("Arial", 11, QFont.Bold) + stage_font.setBold(True) stage_item.setFont(stage_font) - stage_item.setForeground(QColor(ModernStylesheet.COLORS.get('accent', '#0078D4'))) + stage_item.setForeground(QColor("#0078D4")) stage_item.setFlags(stage_item.flags() & ~Qt.ItemIsSelectable) stage_item.setFlags(stage_item.flags() & ~Qt.ItemIsEnabled) stage_item.setData(Qt.UserRole, "stage_header") @@ -587,7 +588,7 @@ class WaterQualityGUI(QMainWindow): # 添加该阶段的所有步骤 for step_id, step_display in steps: - item = QListWidgetItem(f" └─ {step_display}") + item = QListWidgetItem(f" {step_display}") item.setData(Qt.UserRole, step_id) self.step_name_map[step_display] = step_id diff --git a/src/gui/water_quality_gui_v2.py b/src/gui/water_quality_gui_v2.py index 5f9e5c4..98237f2 100644 --- a/src/gui/water_quality_gui_v2.py +++ b/src/gui/water_quality_gui_v2.py @@ -347,15 +347,16 @@ class WaterQualityGUI(QMainWindow): for stage_idx, (stage_name, steps) in enumerate(process_stages.items()): stage_item = QListWidgetItem(stage_name) stage_font = QFont("Arial", 11, QFont.Bold) + stage_font.setBold(True) stage_item.setFont(stage_font) - stage_item.setForeground(QColor(ModernStylesheet.COLORS.get('accent', '#0078D4'))) + stage_item.setForeground(QColor("#0078D4")) stage_item.setFlags(stage_item.flags() & ~Qt.ItemIsSelectable) stage_item.setFlags(stage_item.flags() & ~Qt.ItemIsEnabled) stage_item.setData(Qt.UserRole, "stage_header") self._step_list.addItem(stage_item) for step_id, step_display in steps: - item = QListWidgetItem(f" └─ {step_display}") + item = QListWidgetItem(f" {step_display}") item.setData(Qt.UserRole, step_id) step_font = QFont("Arial", 10) item.setFont(step_font)