Files
cmshoppe/docs/tasks/T-573.md
T

77 lines
4.2 KiB
Markdown
Raw 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.
---
id: T-573
title: ②封面画廊候选图横向滚动内容宽度修复
phase: 7
deps: [T-567, T-569]
status: DONE
created: 2026-07-09
---
## 问题 / 背景
②AI生成模块中,双击任务行打开封面画廊后,如果某条任务有多张生成封面候选图,弹窗里可能出现第一张图显示不完整、被第二张图遮盖一半的现象。
当前 `CoverGalleryDialog._candidate_panel()` 使用 `QScrollArea` + `QHBoxLayout` 横向展示候选图:
```python
scroll = QScrollArea()
scroll.setWidgetResizable(False)
content = QWidget()
self.candidate_layout = QHBoxLayout(content)
...
scroll.setWidget(content)
```
每个候选图 item 固定宽度约 `THUMBNAIL_SIZE + 16`,候选之间还有 spacing。但外层 `content` 没有按候选图数量显式撑开宽度,也没有在初始化或 `_rebuild_candidate_items()` 后根据 `candidate_layout.sizeHint()` 更新 `content` 尺寸。`setWidgetResizable(False)` 时,`QScrollArea` 不会自动帮内部 content 扩到实际所需宽度,导致横向布局被压缩/裁剪,表现为候选图重叠或遮挡。
T-568/T-569 后封面画廊支持切换任务和重新生成,候选图列表会动态重建;如果重建后仍沿用旧 content 尺寸,更容易出现多图显示错位。
## 方案
- `app/gui/tabs/generate.py`
- 在 `CoverGalleryDialog` 中保存候选图滚动区和内容容器引用,例如 `self.candidate_scroll`、`self.candidate_content`。
- 抽出 `_sync_candidate_content_size()`:
- 根据 `self.candidate_layout.sizeHint()` 或候选数量计算内容最小宽度。
- `minimumWidth` 至少覆盖所有候选 item 宽度 + spacing + margins。
- `minimumHeight` 至少覆盖缩略图、radio、meta 文案所需高度。
- 调用 `adjustSize()` 或 `resize(sizeHint)`,确保横向滚动条按真实内容宽度工作。
- 在 `_candidate_panel()` 初始化候选后调用一次。
- 在 `_rebuild_candidate_items()` 重建候选后再次调用,覆盖任务切换和重新生成后的动态列表。
- 可保留 `scroll.setWidgetResizable(False)`,但必须显式设置 content 尺寸;或改为 `setWidgetResizable(True)` 并同时设置 content `minimumWidth`,避免 viewport 变窄时重新压缩候选图。
- `tests/test_gui.py`
- 增加封面画廊多候选图布局测试:准备 3 张以上候选图,断言 `candidate_content.minimumWidth()` / `sizeHint().width()` 大于等于所有候选 item 宽度和间距。
- 增加切换任务后的测试:从候选较少任务切到候选较多任务后,content 宽度重新同步,不沿用旧宽度。
## 验收要点
- 多张生成封面候选图在画廊中横向排列,不互相遮盖。
- 候选图数量超过可视宽度时出现横向滚动,滚动后每张图都能完整查看。
- 切换上一条/下一条任务后,候选区宽度按新任务候选数量重新计算。
- 单张候选图、无候选图、图片读取失败占位状态不回归。
- 不影响 T-572 的 `↑ / ↓` 记录切换和输入控件保护。
- 验证命令:
- `py -3.10 -m unittest tests.test_gui`
- `python -m ruff check app tests main.py`
- `py -3.10 -m compileall app main.py`
- `py -3.10 -m unittest discover -s tests`
- `git diff --check`
## 边界(不改什么)
- 不改候选图文件发现规则 `image_paths.list_task_cover_candidates()`。
- 不改封面保存、重新生成、未保存选择确认、上一条/下一条切换逻辑。
- 不改 AI/cmhub、DB schema、Excel、③更新蝦皮或 CDP/Shopee 交互。
## 执行记录
- 2026-07-09:已完成。
- `app/gui/tabs/generate.py`:`CoverGalleryDialog` 保存 `candidate_scroll` / `candidate_content` 引用,新增 `_sync_candidate_content_size()`;候选图初始化和 `_rebuild_candidate_items()` 后按候选数量、item 宽度、spacing 与 layout sizeHint 同步 content 最小尺寸和实际尺寸,保留横向滚动行为。
- `tests/test_gui.py`:新增多候选图内容宽度测试,以及从少候选任务切换到多候选任务后的宽度重新同步测试。
- 验证通过:
- `py -3.10 -m unittest tests.test_gui`
- `python -m ruff check app tests main.py`
- `py -3.10 -m compileall app main.py`
- `py -3.10 -m unittest discover -s tests`
- `git diff --check`