refactor(gui/sidebar): 重组导航为四模块 + 扁平无框蓝色高亮主题 + 中括号移除
数据层(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 失效兜底 + 代码意图自解释 末尾迭代:四个模块名移除 [ ] 中括号(极简风)
This commit is contained in:
@ -29,14 +29,14 @@ from src.gui.panels.step13_report_panel import Step13ReportPanel
|
|||||||
|
|
||||||
PANEL_REGISTRY = [
|
PANEL_REGISTRY = [
|
||||||
# ═══════════════════════════════════════════════════════════════
|
# ═══════════════════════════════════════════════════════════════
|
||||||
# 阶段一:影像预处理
|
# 模块一 影像预处理
|
||||||
# ═══════════════════════════════════════════════════════════════
|
# ═══════════════════════════════════════════════════════════════
|
||||||
{
|
{
|
||||||
'step_id': 'step1',
|
'step_id': 'step1',
|
||||||
'class_ref': Step1Panel,
|
'class_ref': Step1Panel,
|
||||||
'title': '水域掩膜',
|
'title': '水域掩膜',
|
||||||
'icon': '1.png',
|
'icon': '1.png',
|
||||||
'stage': '阶段一:影像预处理',
|
'stage': '模块一 影像预处理',
|
||||||
'display_name': '1. 水域掩膜生成',
|
'display_name': '1. 水域掩膜生成',
|
||||||
'dependencies': None,
|
'dependencies': None,
|
||||||
'constructor_kwargs': None,
|
'constructor_kwargs': None,
|
||||||
@ -46,7 +46,7 @@ PANEL_REGISTRY = [
|
|||||||
'class_ref': Step2Panel,
|
'class_ref': Step2Panel,
|
||||||
'title': '耀斑检测',
|
'title': '耀斑检测',
|
||||||
'icon': '2.png',
|
'icon': '2.png',
|
||||||
'stage': '阶段一:影像预处理',
|
'stage': '模块一 影像预处理',
|
||||||
'display_name': '2. 耀斑区域识别',
|
'display_name': '2. 耀斑区域识别',
|
||||||
# 架构解耦(2026-06-22):dict 键名 = 下游目标控件真实属性名;
|
# 架构解耦(2026-06-22):dict 键名 = 下游目标控件真实属性名;
|
||||||
# 第三元素 source_attr = 上游源控件真实属性名(panel_factory 回放端使用)
|
# 第三元素 source_attr = 上游源控件真实属性名(panel_factory 回放端使用)
|
||||||
@ -63,7 +63,7 @@ PANEL_REGISTRY = [
|
|||||||
'class_ref': Step3Panel,
|
'class_ref': Step3Panel,
|
||||||
'title': '耀斑去除',
|
'title': '耀斑去除',
|
||||||
'icon': '3.png',
|
'icon': '3.png',
|
||||||
'stage': '阶段一:影像预处理',
|
'stage': '模块一 影像预处理',
|
||||||
'display_name': '3. 耀斑去除与修复',
|
'display_name': '3. 耀斑去除与修复',
|
||||||
# 架构解耦(2026-06-22):dict 键名 = 下游目标控件真实属性名
|
# 架构解耦(2026-06-22):dict 键名 = 下游目标控件真实属性名
|
||||||
'dependencies': {
|
'dependencies': {
|
||||||
@ -76,14 +76,14 @@ PANEL_REGISTRY = [
|
|||||||
},
|
},
|
||||||
|
|
||||||
# ═══════════════════════════════════════════════════════════════
|
# ═══════════════════════════════════════════════════════════════
|
||||||
# 阶段二:样本数据准备
|
# 模块二 特征工程与数据
|
||||||
# ═══════════════════════════════════════════════════════════════
|
# ═══════════════════════════════════════════════════════════════
|
||||||
{
|
{
|
||||||
'step_id': 'step4_sampling',
|
'step_id': 'step4_sampling',
|
||||||
'class_ref': Step4SamplingPanel,
|
'class_ref': Step4SamplingPanel,
|
||||||
'title': '采样点布设',
|
'title': '采样点布设',
|
||||||
'icon': '4.png',
|
'icon': '4.png',
|
||||||
'stage': '阶段二:样本数据准备',
|
'stage': '模块二 特征工程与数据',
|
||||||
'display_name': '4. 采样点布设',
|
'display_name': '4. 采样点布设',
|
||||||
# 架构解耦(2026-06-22):dict 键名 = 下游目标控件真实属性名;
|
# 架构解耦(2026-06-22):dict 键名 = 下游目标控件真实属性名;
|
||||||
# 第三元素 source_attr = 上游源控件真实属性名(panel_factory 回放端使用)
|
# 第三元素 source_attr = 上游源控件真实属性名(panel_factory 回放端使用)
|
||||||
@ -100,7 +100,7 @@ PANEL_REGISTRY = [
|
|||||||
'class_ref': Step5CleanPanel,
|
'class_ref': Step5CleanPanel,
|
||||||
'title': '数据清洗',
|
'title': '数据清洗',
|
||||||
'icon': '5.png',
|
'icon': '5.png',
|
||||||
'stage': '阶段二:样本数据准备',
|
'stage': '模块二 特征工程与数据',
|
||||||
'display_name': '5. 数据清洗',
|
'display_name': '5. 数据清洗',
|
||||||
# 业务要求保持输入源独立,不自动抓取 step4_sampling 的输出
|
# 业务要求保持输入源独立,不自动抓取 step4_sampling 的输出
|
||||||
'dependencies': None,
|
'dependencies': None,
|
||||||
@ -111,7 +111,7 @@ PANEL_REGISTRY = [
|
|||||||
'class_ref': Step6FeaturePanel,
|
'class_ref': Step6FeaturePanel,
|
||||||
'title': '光谱特征',
|
'title': '光谱特征',
|
||||||
'icon': '6.png',
|
'icon': '6.png',
|
||||||
'stage': '阶段二:样本数据准备',
|
'stage': '模块二 特征工程与数据',
|
||||||
'display_name': '6. 光谱特征提取',
|
'display_name': '6. 光谱特征提取',
|
||||||
# 架构解耦(2026-06-22):dict 键名 = 下游目标控件真实属性名
|
# 架构解耦(2026-06-22):dict 键名 = 下游目标控件真实属性名
|
||||||
'dependencies': {
|
'dependencies': {
|
||||||
@ -131,7 +131,7 @@ PANEL_REGISTRY = [
|
|||||||
'class_ref': Step7View,
|
'class_ref': Step7View,
|
||||||
'title': '水质光谱指数计算',
|
'title': '水质光谱指数计算',
|
||||||
'icon': '7.png',
|
'icon': '7.png',
|
||||||
'stage': '阶段二:样本数据准备',
|
'stage': '模块二 特征工程与数据',
|
||||||
'display_name': '7. 水质指数计算',
|
'display_name': '7. 水质指数计算',
|
||||||
# 架构解耦(2026-06-22):dict 键名 = 下游目标控件真实属性名;
|
# 架构解耦(2026-06-22):dict 键名 = 下游目标控件真实属性名;
|
||||||
# 第三元素 source_attr = 上游源控件真实属性名
|
# 第三元素 source_attr = 上游源控件真实属性名
|
||||||
@ -143,14 +143,14 @@ PANEL_REGISTRY = [
|
|||||||
},
|
},
|
||||||
|
|
||||||
# ═══════════════════════════════════════════════════════════════
|
# ═══════════════════════════════════════════════════════════════
|
||||||
# 阶段三:模型构建与训练
|
# 模块三 模型训练与反演
|
||||||
# ═══════════════════════════════════════════════════════════════
|
# ═══════════════════════════════════════════════════════════════
|
||||||
{
|
{
|
||||||
'step_id': 'step8_ml_train',
|
'step_id': 'step8_ml_train',
|
||||||
'class_ref': Step8MlTrainPanel,
|
'class_ref': Step8MlTrainPanel,
|
||||||
'title': '机器学习建模',
|
'title': '机器学习建模',
|
||||||
'icon': '8.png',
|
'icon': '8.png',
|
||||||
'stage': '阶段三:模型构建与训练',
|
'stage': '模块三 模型训练与反演',
|
||||||
'display_name': '8. 机器学习建模',
|
'display_name': '8. 机器学习建模',
|
||||||
# 架构解耦(2026-06-22):dict 键名 = 下游目标控件真实属性名
|
# 架构解耦(2026-06-22):dict 键名 = 下游目标控件真实属性名
|
||||||
'dependencies': {
|
'dependencies': {
|
||||||
@ -161,14 +161,14 @@ PANEL_REGISTRY = [
|
|||||||
},
|
},
|
||||||
|
|
||||||
# ═══════════════════════════════════════════════════════════════
|
# ═══════════════════════════════════════════════════════════════
|
||||||
# 阶段四:预测与成果输出
|
# 模块三 模型训练与反演(续)→ 模块四 制图与成果汇编
|
||||||
# ═══════════════════════════════════════════════════════════════
|
# ═══════════════════════════════════════════════════════════════
|
||||||
{
|
{
|
||||||
'step_id': 'step9_ml_predict',
|
'step_id': 'step9_ml_predict',
|
||||||
'class_ref': Step9MlPredictPanel,
|
'class_ref': Step9MlPredictPanel,
|
||||||
'title': '机器学习预测',
|
'title': '机器学习预测',
|
||||||
'icon': '10.png',
|
'icon': '10.png',
|
||||||
'stage': '阶段四:预测与成果输出',
|
'stage': '模块三 模型训练与反演',
|
||||||
'display_name': '9. 机器学习预测',
|
'display_name': '9. 机器学习预测',
|
||||||
# 架构解耦(2026-06-22):dict 键名 = 下游目标控件真实属性名;
|
# 架构解耦(2026-06-22):dict 键名 = 下游目标控件真实属性名;
|
||||||
# 第三元素 source_attr = 上游源控件真实属性名
|
# 第三元素 source_attr = 上游源控件真实属性名
|
||||||
@ -183,7 +183,7 @@ PANEL_REGISTRY = [
|
|||||||
'class_ref': Step10WatercolorPanel,
|
'class_ref': Step10WatercolorPanel,
|
||||||
'title': '水色指数反演',
|
'title': '水色指数反演',
|
||||||
'icon': '10.png',
|
'icon': '10.png',
|
||||||
'stage': '阶段四:预测与成果输出',
|
'stage': '模块三 模型训练与反演',
|
||||||
'display_name': '10. 水色指数反演',
|
'display_name': '10. 水色指数反演',
|
||||||
# 架构解耦(2026-06-22):dict 键名 = 下游目标控件真实属性名;
|
# 架构解耦(2026-06-22):dict 键名 = 下游目标控件真实属性名;
|
||||||
# 第三元素 source_attr = 上游源控件真实属性名
|
# 第三元素 source_attr = 上游源控件真实属性名
|
||||||
@ -200,7 +200,7 @@ PANEL_REGISTRY = [
|
|||||||
'class_ref': Step11MapPanel,
|
'class_ref': Step11MapPanel,
|
||||||
'title': '专题图生成',
|
'title': '专题图生成',
|
||||||
'icon': '10.png',
|
'icon': '10.png',
|
||||||
'stage': '阶段四:预测与成果输出',
|
'stage': '模块四 制图与成果汇编',
|
||||||
'display_name': '11. 专题图生成',
|
'display_name': '11. 专题图生成',
|
||||||
# 架构解耦(2026-06-22):dict 键名 = 下游目标控件真实属性名
|
# 架构解耦(2026-06-22):dict 键名 = 下游目标控件真实属性名
|
||||||
'dependencies': {
|
'dependencies': {
|
||||||
@ -218,7 +218,7 @@ PANEL_REGISTRY = [
|
|||||||
'class_ref': Step12VizPanel,
|
'class_ref': Step12VizPanel,
|
||||||
'title': '可视化',
|
'title': '可视化',
|
||||||
'icon': '9.png',
|
'icon': '9.png',
|
||||||
'stage': '阶段四:预测与成果输出',
|
'stage': '模块四 制图与成果汇编',
|
||||||
'display_name': '12. 可视化展示',
|
'display_name': '12. 可视化展示',
|
||||||
'dependencies': None,
|
'dependencies': None,
|
||||||
'constructor_kwargs': None,
|
'constructor_kwargs': None,
|
||||||
@ -228,7 +228,7 @@ PANEL_REGISTRY = [
|
|||||||
'class_ref': Step13ReportPanel,
|
'class_ref': Step13ReportPanel,
|
||||||
'title': '报告生成',
|
'title': '报告生成',
|
||||||
'icon': '10.png',
|
'icon': '10.png',
|
||||||
'stage': '阶段四:预测与成果输出',
|
'stage': '模块四 制图与成果汇编',
|
||||||
'display_name': '13. 分析报告生成',
|
'display_name': '13. 分析报告生成',
|
||||||
'dependencies': None,
|
'dependencies': None,
|
||||||
'constructor_kwargs': {'main_window'}, # 需要注入 main_window=self
|
'constructor_kwargs': {'main_window'}, # 需要注入 main_window=self
|
||||||
|
|||||||
@ -538,8 +538,21 @@ class ModernStylesheet:
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_sidebar_stylesheet():
|
def get_sidebar_stylesheet():
|
||||||
"""获取左侧边栏样式表"""
|
"""获取左侧边栏样式表
|
||||||
|
|
||||||
|
设计主题:扁平无框 + 蓝色高亮。
|
||||||
|
结构契约:
|
||||||
|
- 分类头 stage_header 项已通过 setFlags(~Qt.ItemIsEnabled) 禁用,
|
||||||
|
因此 :!enabled 选择器可精确锁定分类头(蓝色加粗)。
|
||||||
|
- 可点击的步骤项保持 enabled,进入 :enabled 通道
|
||||||
|
(padding/margin 留白 + 圆角 + hover/selected 蓝色现代感)。
|
||||||
|
"""
|
||||||
colors = ModernStylesheet.COLORS
|
colors = ModernStylesheet.COLORS
|
||||||
|
# 主题色板(蓝色高亮)
|
||||||
|
stage_header_color = '#0078D4' # 分类头:亮蓝色加粗
|
||||||
|
step_hover_bg = '#F0F4F8' # hover(极浅蓝灰)
|
||||||
|
step_selected_bg = '#0078D4' # selected(饱和蓝)
|
||||||
|
step_selected_fg = '#FFFFFF' # selected(白字)
|
||||||
return f"""
|
return f"""
|
||||||
QWidget {{
|
QWidget {{
|
||||||
background-color: {colors['panel_bg']};
|
background-color: {colors['panel_bg']};
|
||||||
@ -549,22 +562,47 @@ class ModernStylesheet:
|
|||||||
color: {colors['text_primary']};
|
color: {colors['text_primary']};
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}}
|
}}
|
||||||
|
/* ── 容器:无框化、零描边、零焦点环 ── */
|
||||||
QListWidget {{
|
QListWidget {{
|
||||||
background-color: {colors['panel_bg']};
|
border: none;
|
||||||
border: 0px;
|
outline: none;
|
||||||
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 {{
|
|
||||||
background-color: transparent;
|
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;
|
font-weight: bold;
|
||||||
}}
|
}}
|
||||||
|
/* ── 分隔符占位项:完全透明,零干扰 ── */
|
||||||
|
QListWidget::item[separator="true"] {{
|
||||||
|
background-color: transparent;
|
||||||
|
border: none;
|
||||||
|
padding: 0px;
|
||||||
|
margin: 0px;
|
||||||
|
min-height: 4px;
|
||||||
|
}}
|
||||||
"""
|
"""
|
||||||
|
|||||||
@ -578,8 +578,9 @@ class WaterQualityGUI(QMainWindow):
|
|||||||
# 添加阶段标题项(可视化分组)
|
# 添加阶段标题项(可视化分组)
|
||||||
stage_item = QListWidgetItem(stage_name)
|
stage_item = QListWidgetItem(stage_name)
|
||||||
stage_font = QFont("Arial", 11, QFont.Bold)
|
stage_font = QFont("Arial", 11, QFont.Bold)
|
||||||
|
stage_font.setBold(True)
|
||||||
stage_item.setFont(stage_font)
|
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.ItemIsSelectable)
|
||||||
stage_item.setFlags(stage_item.flags() & ~Qt.ItemIsEnabled)
|
stage_item.setFlags(stage_item.flags() & ~Qt.ItemIsEnabled)
|
||||||
stage_item.setData(Qt.UserRole, "stage_header")
|
stage_item.setData(Qt.UserRole, "stage_header")
|
||||||
@ -587,7 +588,7 @@ class WaterQualityGUI(QMainWindow):
|
|||||||
|
|
||||||
# 添加该阶段的所有步骤
|
# 添加该阶段的所有步骤
|
||||||
for step_id, step_display in steps:
|
for step_id, step_display in steps:
|
||||||
item = QListWidgetItem(f" └─ {step_display}")
|
item = QListWidgetItem(f" {step_display}")
|
||||||
item.setData(Qt.UserRole, step_id)
|
item.setData(Qt.UserRole, step_id)
|
||||||
|
|
||||||
self.step_name_map[step_display] = step_id
|
self.step_name_map[step_display] = step_id
|
||||||
|
|||||||
@ -347,15 +347,16 @@ class WaterQualityGUI(QMainWindow):
|
|||||||
for stage_idx, (stage_name, steps) in enumerate(process_stages.items()):
|
for stage_idx, (stage_name, steps) in enumerate(process_stages.items()):
|
||||||
stage_item = QListWidgetItem(stage_name)
|
stage_item = QListWidgetItem(stage_name)
|
||||||
stage_font = QFont("Arial", 11, QFont.Bold)
|
stage_font = QFont("Arial", 11, QFont.Bold)
|
||||||
|
stage_font.setBold(True)
|
||||||
stage_item.setFont(stage_font)
|
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.ItemIsSelectable)
|
||||||
stage_item.setFlags(stage_item.flags() & ~Qt.ItemIsEnabled)
|
stage_item.setFlags(stage_item.flags() & ~Qt.ItemIsEnabled)
|
||||||
stage_item.setData(Qt.UserRole, "stage_header")
|
stage_item.setData(Qt.UserRole, "stage_header")
|
||||||
self._step_list.addItem(stage_item)
|
self._step_list.addItem(stage_item)
|
||||||
|
|
||||||
for step_id, step_display in steps:
|
for step_id, step_display in steps:
|
||||||
item = QListWidgetItem(f" └─ {step_display}")
|
item = QListWidgetItem(f" {step_display}")
|
||||||
item.setData(Qt.UserRole, step_id)
|
item.setData(Qt.UserRole, step_id)
|
||||||
step_font = QFont("Arial", 10)
|
step_font = QFont("Arial", 10)
|
||||||
item.setFont(step_font)
|
item.setFont(step_font)
|
||||||
|
|||||||
Reference in New Issue
Block a user