更正措辞:症状是弹窗只画一半/显示不全,界面不卡死;根因是弹窗在紧邻 整表重绘未画完时就 exec(),与导入耗时无关。修法(QTimer.singleShot(0) 延迟弹窗到重绘画完再开)不变。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
50 lines
3.5 KiB
Markdown
50 lines
3.5 KiB
Markdown
---
|
||
id: T-582
|
||
title: 修复①导入 Excel 后完成弹窗偶发只显示一半(延迟一拍弹窗 + 可选 HiDPI 一行)
|
||
phase: 7
|
||
deps: []
|
||
status: TODO
|
||
created: 2026-07-10
|
||
---
|
||
|
||
## 问题 / 背景
|
||
|
||
用户反馈:①采集导入 Excel 后的完成/错误弹窗**偶发只显示一半、显示不全**。**界面本身不卡死**——导入通常很快、无可感知冻结,纯粹是弹窗画不全。「偶尔」也排除纯 HiDPI 缩放(那会稳定半截),指向绘制时序竞态。
|
||
|
||
已核代码事实:①导入返回后在**同一调用栈**里紧接 `refresh_tasks()`(整表重绘)后立即 `exec()` 弹窗(`app/gui/tabs/collect.py:242` 起)。模态框在这次整表重绘尚未画完时就打开,首帧几何/内容没算稳 → 偶发只画一半。**与导入是否耗时无关**:只要弹窗在待处理重绘之前 `exec()` 就可能半截,所以修法不是"别阻塞",而是"让弹窗晚一拍、等重绘画完再开"。
|
||
|
||
范围收敛:本任务**只修导入这一处弹窗**,不建统一弹窗 helper、不重构其它 `QMessageBox` 调用点、不改导入线程模型(导入 worker 化不在本任务)。
|
||
|
||
## 方案(改哪个文件、改成什么)
|
||
|
||
### 1. 让导入完成/错误弹窗晚一拍弹(`app/gui/tabs/collect.py`)
|
||
- 导入返回后,把该路径上的弹窗(`_show_error` 失败框、账号未就绪 warning、导入结果通知框等**导入链路**的通知类弹窗)改为用 `QTimer.singleShot(0, lambda: <弹窗>)` 推迟显示——让紧邻的整表重绘(`refresh_tasks`)先在事件循环里冲刷完,再打开模态框。
|
||
- 只改导入链路的通知类弹窗;不动 question/确认类(导入链路本身无需返回值的确认)。
|
||
- 仅 collect.py 导入相关处,不外扩。
|
||
|
||
### 2.(可选保险)启动加 HiDPI 舍入策略(`app/gui/__init__.py`)
|
||
- `QApplication` 创建前设 `QGuiApplication.setHighDpiScaleFactorRoundingPolicy(Qt.HighDpiScaleFactorRoundingPolicy.PassThrough)`(`main()` 里 `app = QApplication.instance() or QApplication(sys.argv)` 之前;实例已存在时跳过避免告警)。
|
||
- 零风险、对整体弹窗清晰度有益;如实现时评估有副作用可省略,验收不强制。
|
||
|
||
## 验收要点
|
||
- 导入完成/失败后的通知类弹窗经 `QTimer.singleShot(0, ...)` 延迟显示(单测:mock `QTimer.singleShot` 断言被用于导入完成/错误弹窗路径;不真正弹窗)。
|
||
- 导入结果/错误的既有行为(stats 更新、run_log、状态栏文案、`_show_error` 内容)不回归。
|
||
- 若采纳 HiDPI 行:启动设置在 QApplication 创建前、不回归启动。
|
||
- 未改动导入链路以外的弹窗调用点(`git diff` 范围仅 collect.py 导入链路 +(可选)__init__.py 一行)。
|
||
- 验证命令(unittest,不引入 pytest;GUI 测试用 offscreen):
|
||
- `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`
|
||
|
||
## 边界(不改什么)
|
||
- 不建统一弹窗 helper、不收敛/替换其它模块的 `QMessageBox` 调用。
|
||
- 不把①导入改成 worker 线程(如后续要治界面卡死另立任务/backlog)。
|
||
- 不改弹窗文案/业务语义、不改 `excel.import_tasks` 解析入库逻辑。
|
||
- 不改 CDP/DB/AI/cmhub、主窗口尺寸逻辑。
|
||
|
||
## 执行记录
|
||
|
||
(做完在这里写:改了什么文件、跑了什么验证命令及结果、遇到的阻塞、关键决策。)
|