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

337 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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
**关联提交**: (待提交)