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

4.0 KiB

id, title, phase, deps, status, created
id title phase deps status created
T-572 ②封面画廊打开后上下键切换记录不受按钮焦点影响 7
T-569
DONE 2026-07-09

问题 / 背景

T-569 给②AI生成的封面画廊 CoverGalleryDialog 增加了「上一条 / 下一条」按钮和 ↑ / ↓ 键切换当前可见任务记录。但真实使用中,用户双击②表格某条记录打开弹窗后,不做任何点击,直接按 ↓ / ↑,无法切换到其他行的图片。

原因是弹窗打开后 Qt 可能把焦点默认放在某个 QPushButton 上,例如「上一条」「下一条」「重新生成」「保存」「取消」。当前 _should_consume_navigation_key() 明确把 QPushButton 排除:

return not isinstance(focus, (QPushButton, QLineEdit, QPlainTextEdit, QComboBox, QSpinBox))

所以当焦点在按钮上时,CoverGalleryDialog.keyPressEvent() 不会调用 switch_task(),上下键被按钮焦点/默认事件链消费。T-569 单测只覆盖了候选 radio 获得焦点时的方向键行为,没有覆盖弹窗刚打开、焦点在按钮上的真实路径。

方案

  • app/gui/tabs/generate.py

    • 调整 CoverGalleryDialog 的方向键处理,让 ↑ / ↓ 在焦点位于按钮、图片、空白区域、radio 时都切换上一条/下一条。
    • 仍保留输入类控件默认行为:焦点在 QLineEdit、QPlainTextEdit、QComboBox、QSpinBox 等输入/选择控件时,不消费上下键。
    • 可选实现方式:
      • 修改 _should_consume_navigation_key(),不再把 QPushButton 视为排除项;或
      • 给弹窗安装 eventFilter / QShortcut 做窗口级快捷键,但必须避免输入类控件被抢键。
    • 不改「上一条 / 下一条」按钮点击逻辑,不改未保存选择确认逻辑。
  • tests/test_gui.py

    • 增加回归测试:创建 CoverGalleryDialog 后把焦点放到 next_button 或 save_button,发送 Qt.Key_Down,应切到下一条。
    • 增加保护测试:焦点在输入类控件时,Qt.Key_Down 不触发 switch_task()。

验收要点

  • 双击②AI生成表格某条记录打开封面画廊后,不点击任何控件,直接按 ↓ 可以切换到下一条记录;按 ↑ 可以切回上一条记录。
  • 焦点在「上一条 / 下一条 / 重新生成 / 保存 / 取消」按钮上时,↑ / ↓ 仍切换记录。
  • 焦点在候选 radio 上时,↑ / ↓ 仍切换记录,且不会改变 radio 选中的候选封面。
  • 焦点在输入/选择类控件上时,不抢占上下键,保留控件默认行为。
  • 切换记录仍走 T-569 的未保存选择确认;不绕过「保存 / 不保存 / 取消」。
  • 验证命令:
    • 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

边界(不改什么)

  • 不改 CoverGalleryDialog.switch_task() 的数据切换逻辑。
  • 不改封面候选保存、重新生成、未保存选择确认。
  • 不改 AI/cmhub、DB schema、Excel、③更新蝦皮或 CDP/Shopee 交互。

执行记录

  • 2026-07-09:完成 T-572。
    • app/gui/tabs/generate.py:调整 CoverGalleryDialog._should_consume_navigation_key(),不再把 QPushButton 作为方向键切换的排除焦点;同时给弹窗和子控件安装 eventFilter,处理真实 Qt 运行时按键先发给按钮/radio 等子控件、父弹窗 keyPressEvent() 收不到的路径。焦点在上一条/下一条/重新生成/保存/取消等按钮上时,↑ / ↓ 会切换记录;焦点在输入类控件上仍不抢键。
    • tests/test_gui.py:新增按钮焦点下通过真实子控件事件分发 Qt.Key_Down 可切到下一条的回归测试;新增输入框焦点下 Qt.Key_Down 不切换记录的保护测试;保留 radio 焦点不改变候选选择的既有测试。
    • 验证通过: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。