# Step1Panel UI 联动逻辑优化说明 ## 📋 修改概览 本次优化针对 Step1Panel(水域掩膜生成步骤)的 UI 联动逻辑进行了深度重构,主要解决了: 1. ✅ 输出掩膜组件与单选按钮的深度绑定 2. ✅ 路径显示的斜杠混用问题 3. ✅ 底层运行逻辑的兼容性 --- ## 🎯 核心改进 ### 1. 输出掩膜的显示/隐藏与单选按钮深度绑定 #### 修改位置:`Step1Panel.update_ui_state()` **原逻辑问题**: - 输出掩膜在两种模式下都显示,不符合业务逻辑 - "使用现有掩膜文件"时不需要指定输出路径 **新逻辑**: ```python 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. 修复路径斜杠混用问题 #### 修改位置 1:`Step1Panel._auto_fill_output_path()` (新增方法) **核心改进**:统一使用正斜杠 `/`,避免 Windows 下的 `\` 和 `/` 混用 ```python 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('\\', '/')` 统一转换为正斜杠 - 在界面显示前完成转换,确保用户看到的路径一致 #### 修改位置 2:`Step1Panel.update_work_directory()` **原逻辑问题**: - 开机时直接填充路径,不考虑当前选择的模式 - 没有斜杠格式化 **新逻辑**: ```python 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 - "使用现有掩膜"模式下传递空路径可能导致底层错误 **新逻辑**: ```python 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自动生成"模式:传递用户选择的路径 **底层兼容性**: ```python # 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()` 填充输出掩膜路径 - 不考虑当前的单选按钮状态 **新逻辑**: ```python 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:用户点击"独立运行此步骤" #### 当前选择:"使用现有掩膜文件" ```python 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自动生成" ```python 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 **关联提交**: (待提交)