Files
WQ_GUI/Step1Panel_UI联动优化说明.md

11 KiB
Raw Permalink Blame History

Step1Panel UI 联动逻辑优化说明

📋 修改概览

本次优化针对 Step1Panel水域掩膜生成步骤的 UI 联动逻辑进行了深度重构,主要解决了:

  1. 输出掩膜组件与单选按钮的深度绑定
  2. 路径显示的斜杠混用问题
  3. 底层运行逻辑的兼容性

🎯 核心改进

1. 输出掩膜的显示/隐藏与单选按钮深度绑定

修改位置:Step1Panel.update_ui_state()

原逻辑问题

  • 输出掩膜在两种模式下都显示,不符合业务逻辑
  • "使用现有掩膜文件"时不需要指定输出路径

新逻辑

def update_ui_state(self):
    """根据选择的掩膜生成方式更新UI状态使用显示/隐藏控制)"""
    use_ndwi = self.use_ndwi_radio.isChecked()

    # 动态显示/隐藏组件
    if use_ndwi:
        # 使用NDWI模式隐藏掩膜文件显示NDWI参数和输出掩膜
        self.mask_file.setVisible(False)
        self.ndwi_group.setVisible(True)
        self.output_file.setVisible(True)  # 显示输出掩膜路径
        
        # 当切换到NDWI模式时如果工作目录已设置自动填充输出路径
        if hasattr(self, 'work_dir') and self.work_dir:
            self._auto_fill_output_path()
    else:
        # 使用现有掩膜模式显示掩膜文件隐藏NDWI参数和输出掩膜
        self.mask_file.setVisible(True)
        self.ndwi_group.setVisible(False)
        self.output_file.setVisible(False)  # 隐藏输出掩膜路径

    # 参考影像在两种模式下都显示
    self.img_file.setVisible(True)

行为说明

模式 掩膜文件 NDWI参数组 输出掩膜 参考影像
使用现有掩膜文件 显示 隐藏 隐藏 显示
使用NDWI自动生成 隐藏 显示 显示 显示

2. 修复路径斜杠混用问题

修改位置 1Step1Panel._auto_fill_output_path() (新增方法)

核心改进:统一使用正斜杠 /,避免 Windows 下的 \/ 混用

def _auto_fill_output_path(self):
    """
    自动填充输出掩膜路径仅在NDWI模式下
    确保路径使用正斜杠,避免斜杠混用
    """
    if not hasattr(self, 'work_dir') or not self.work_dir:
        return
    
    # 生成输出掩膜的完整路径
    output_dir = os.path.join(self.work_dir, "1_water_mask")
    os.makedirs(output_dir, exist_ok=True)  # 确保目录存在
    
    # 统一使用正斜杠,避免 \ 和 / 混用
    default_output_path = os.path.join(output_dir, "water_mask_out.dat").replace('\\', '/')
    self.output_file.set_path(default_output_path)

关键技术点

  • 使用 os.path.join() 构建路径(适配不同操作系统)
  • 最终通过 .replace('\\', '/') 统一转换为正斜杠
  • 在界面显示前完成转换,确保用户看到的路径一致

修改位置 2Step1Panel.update_work_directory()

原逻辑问题

  • 开机时直接填充路径,不考虑当前选择的模式
  • 没有斜杠格式化

新逻辑

def update_work_directory(self, work_dir):
    """
    保存工作目录引用,用于后续自动填充路径
    
    Args:
        work_dir: 工作目录路径
    """
    if not work_dir:
        return
    
    # 保存工作目录引用
    self.work_dir = work_dir
    
    # 如果当前选中的是NDWI模式立即填充输出路径
    if self.use_ndwi_radio.isChecked():
        self._auto_fill_output_path()

改进说明

  • 只保存工作目录引用,不立即填充
  • 仅在 NDWI 模式下才调用 _auto_fill_output_path()
  • 配合 update_ui_state() 中的切换触发逻辑

3. 底层运行逻辑的兼容性保障

修改位置:Step1Panel.get_config()

原逻辑问题

  • 无论哪种模式,都传递 output_path 给底层 Pipeline
  • "使用现有掩膜"模式下传递空路径可能导致底层错误

新逻辑

def get_config(self):
    """获取配置"""
    use_ndwi = self.use_ndwi_radio.isChecked()
    
    config = {
        'mask_path': None if use_ndwi else self.mask_file.get_path(),
        'use_ndwi': use_ndwi,
        'ndwi_threshold': self.ndwi_threshold.value()
    }
    
    # 参考影像路径(两种模式都可能需要)
    img_path = self.img_file.get_path()
    if img_path:
        config['img_path'] = img_path
    
    # 输出路径仅在NDWI模式下有效
    if use_ndwi:
        output_path = self.output_file.get_path()
        if output_path:
            config['output_path'] = output_path
    else:
        # 使用现有掩膜时不传递output_path避免底层错误尝试保存文件
        config['output_path'] = None
    
    return config

关键改进

  • 根据 use_ndwi 模式动态决定是否传递 output_path
  • "使用现有掩膜"模式:强制 output_path = None
  • "NDWI自动生成"模式:传递用户选择的路径

底层兼容性

# Pipeline 中的处理逻辑(已在之前的提交中实现)
def step1_generate_water_mask(..., output_path: Optional[str] = None):
    if use_ndwi:
        if output_path:
            ndwi_output_path = output_path  # 使用用户指定路径
        else:
            ndwi_output_path = str(self.water_mask_dir / "water_mask_from_ndwi.dat")

4. 主窗口初始化逻辑优化

修改位置:WaterQualityGUI._auto_fill_output_paths()

原逻辑问题

  • 开机时直接调用 set_path() 填充输出掩膜路径
  • 不考虑当前的单选按钮状态

新逻辑

def _auto_fill_output_paths(self):
    """
    根据工作目录自动填充各步骤的输出路径
    注意Step1 的输出路径由 update_work_directory() 根据模式自动控制
    """
    if not self.work_dir:
        return

    # Step1: 只传递工作目录引用,不直接填充路径
    # 路径填充由 Step1Panel 根据单选按钮状态自动控制
    if hasattr(self, 'step1_panel'):
        self.step1_panel.update_work_directory(self.work_dir)

改进说明

  • 主窗口只传递工作目录引用
  • Step1Panel 内部根据模式自主决定是否填充路径
  • 解耦主窗口和子面板的逻辑依赖

🔄 完整的交互流程

场景 1开机启动默认选中"使用现有掩膜文件"

1. 主窗口启动 → QTimer.singleShot(100) 延迟弹窗
2. 用户选择工作目录 D:\work
3. _auto_fill_output_paths() 调用 step1_panel.update_work_directory(work_dir)
4. Step1Panel.update_work_directory() 保存 self.work_dir = "D:\work"
5. 检查当前模式use_existing_radio.isChecked() = True
6. 不调用 _auto_fill_output_path(),输出掩膜保持隐藏
7. 用户看到的界面:
   ✅ 掩膜文件输入框(显示)
   ✅ 参考影像输入框(显示)
   ❌ NDWI参数组隐藏
   ❌ 输出掩膜输入框(隐藏)

场景 2用户切换到"使用NDWI自动生成"

1. 用户点击"使用NDWI自动生成"单选按钮
2. 触发 toggled 信号 → update_ui_state()
3. use_ndwi = True
4. 执行显示/隐藏逻辑:
   - self.mask_file.setVisible(False)  # 隐藏掩膜文件
   - self.ndwi_group.setVisible(True)  # 显示NDWI参数组
   - self.output_file.setVisible(True)  # 显示输出掩膜
5. 检查工作目录hasattr(self, 'work_dir') = True
6. 调用 self._auto_fill_output_path()
7. 生成路径:
   output_dir = os.path.join("D:\work", "1_water_mask")
   path = os.path.join(output_dir, "water_mask_out.dat")
   formatted_path = path.replace('\\', '/')
   # 结果D:/work/1_water_mask/water_mask_out.dat
8. 自动填充到输出掩膜输入框
9. 用户看到的界面:
   ❌ 掩膜文件输入框(隐藏)
   ✅ 参考影像输入框(显示)
   ✅ NDWI参数组显示
   ✅ 输出掩膜输入框显示已填充D:/work/1_water_mask/water_mask_out.dat

场景 3用户点击"独立运行此步骤"

当前选择:"使用现有掩膜文件"

config = {
    'mask_path': "D:/data/existing_mask.dat",  # 用户选择的现有掩膜
    'use_ndwi': False,
    'ndwi_threshold': 0.4,
    'img_path': "D:/data/image.dat",
    'output_path': None  # ✅ 强制为 None不尝试保存
}

当前选择:"使用NDWI自动生成"

config = {
    'mask_path': None,  # NDWI模式不需要现有掩膜
    'use_ndwi': True,
    'ndwi_threshold': 0.4,
    'img_path': "D:/data/image.dat",
    'output_path': "D:/work/1_water_mask/water_mask_out.dat"  # ✅ 传递输出路径
}

测试检查点

UI 显示测试

  • 开机启动后,默认选中"使用现有掩膜文件",输出掩膜输入框应隐藏
  • 切换到"使用NDWI自动生成",输出掩膜输入框应显示,并自动填充路径
  • 切换回"使用现有掩膜文件",输出掩膜输入框应再次隐藏
  • 所有自动填充的路径应使用正斜杠 /,无 \ 混用

路径格式测试

  • 工作目录:D:\work → 输出路径应显示为:D:/work/1_water_mask/water_mask_out.dat
  • 工作目录:C:\Users\Test\Documents → 输出路径应显示为:C:/Users/Test/Documents/1_water_mask/water_mask_out.dat

运行逻辑测试

  • "使用现有掩膜"模式运行:验证 config['output_path'] == None
  • "NDWI自动生成"模式运行:验证 config['output_path'] 为有效路径字符串
  • 底层 Pipeline 接收 output_path=None 时不报错

📝 代码修改总结

文件 修改内容 行数变化
src/gui/water_quality_gui.py Step1Panel.update_ui_state() +6 / -3
src/gui/water_quality_gui.py Step1Panel.update_work_directory() +10 / -8
src/gui/water_quality_gui.py Step1Panel._auto_fill_output_path() (新增) +15 / 0
src/gui/water_quality_gui.py Step1Panel.get_config() +12 / -6
src/gui/water_quality_gui.py WaterQualityGUI._auto_fill_output_paths() +3 / -4

总计:约 +46 / -21


🎯 优化效果

用户体验提升

  1. UI 更简洁:不需要的组件自动隐藏
  2. 路径一致性:所有路径显示统一使用正斜杠
  3. 自动化程度提高:切换模式时自动填充/清空路径

代码质量提升

  1. 职责分离:主窗口不直接操作子面板的路径填充
  2. 逻辑内聚Step1Panel 内部自主管理显示和路径
  3. 兼容性保障:底层 Pipeline 不会收到无效的 output_path

维护性提升

  1. 新增 _auto_fill_output_path() 方法,单一职责
  2. 路径格式化逻辑集中在一处,便于修改
  3. 注释清晰,说明了各模式下的行为

🔧 后续可能的扩展

如果其他步骤也有类似的路径填充需求,可以考虑:

  1. 提取公共方法 format_path_separator(path) 到工具类
  2. FileSelectWidget 类中增加路径格式化的内置支持
  3. 为所有路径输入框添加统一的验证和格式化逻辑

文档生成时间: 2026-05-06
修改人员: DXC
关联提交: (待提交)