进度、停止与任务状态
当翻译页已经有输入文件、输出目录有效且 API 校验通过后,这里说明点击开始按钮后的状态变化、文件计数、百分比、停止请求和任务结束处理。工作流选择及每种模式的输入输出见输出目录与工作流,文件列表的添加、扫描和空列表状态见文件列表与输入。
这部分负责什么
内容包括桌面 Qt 翻译工作区的:
- 开始按钮在准备、启动、运行、停止中和就绪之间的切换。
- 扫描文件、处理文件、已跳过文件、失败文件和完成数量如何进入进度显示。
- 停止请求的取消边界、后台收尾、错误反馈和完成后打开编辑器的询问。
这里不定义检测、OCR、翻译器、修复器或渲染器的算法,也不把进度条当作服务端任务协议。九种工作流的阶段差异仍以工作流页为准。
在翻译页操作
开始任务
- 确认输出目录存在且为目录,并在文件列表中至少保留一个输入项。
- 选择工作流后,点击当前模式的开始按钮。控制器会再次检查任务是否正在运行、上一次扫描/翻译/清理是否仍在后台,以及 API 凭据是否满足当前配置。
- 通过检查后,界面先进入“正在准备文件...”,后台扫描文件夹、压缩包和排除项;扫描完成后才创建翻译 worker,并进入“正在翻译...”。
- 处理开始后,按钮先短暂显示“Starting...”(中文 locale 没有此 key,实际回退为英文 key),约 2 秒后才可点击“停止翻译”。这是为了避免任务刚提交时重复启动或过早停止。
扫描或翻译无法启动时,状态会回到非运行状态并记录“任务启动失败”;无有效图片时回到“就绪”。输出目录、文件列表或 API 校验失败会在任务真正启动前弹窗阻止开始。
查看进度
进度卡片显示一条说明文字、current/total (percentage%) 计数和进度条。current 是已完成或已跳过的原始输入数量,total 是扫描后的原始总数,因此禁用覆盖并跳过已有输出时,跳过项仍计入总数。没有有效总数时显示 0/0 (0%),不会把未知数量伪装成百分比。
说明文字可能包含“批量处理中”或“并发处理中”、平均每张耗时、预计剩余时间、已跳过数量和已失败数量。控制器同时写入状态管理器的 [current/total] message;日志以大约每秒一次的节流频率记录,但首个、最后一个和边界进度会记录。
停止任务
- 任务运行且延迟停止按钮已经启用时,点击“停止翻译”。
- 控制器立即设置停止请求标志,状态消息变为“正在停止...”,按钮禁用并显示“停止中...”。
- 扫描请求 ID 和任务 ID 都递增,使已经排队但晚到的扫描、进度、完成或错误回调失效;worker 的
stop()将运行标志设为 false,并取消当前 asyncio task。 - 扫描 future、翻译 future 和压缩包临时文件清理全部结束后,状态才变为“任务已停止”,进度卡片重置为
0/0 (0%),按钮恢复为当前工作流的开始文案。
停止是协作式取消,不保证中断已经发出的网络请求、模型内部不可取消的同步调用或已经写入磁盘的输出。停止中不可再次点击按钮,也不能用“停止”马上恢复开始状态;若后台仍在收尾,控制器会保持停止中。
处理完成或失败
成功完成后,控制器收集后端返回的已保存路径,按成功、失败和跳过数量设置状态消息并重置进度条。对于会产生编辑器结果的工作流,主窗口会刷新文件快照并询问“翻译完成,成功保存 {count} 个文件。\n\n是否在编辑器中打开结果?”;导出、JSON-only、仅上色、仅超分、仅修复等不适合编辑器的模式不显示该询问。
任务失败时状态为“任务失败”、进度重置,并弹出“翻译错误”对话框。对话框显示友好错误摘要,并提供“打开日志文件夹”;批量任务部分失败时仍会保留成功结果,同时在完成状态中列出成功和失败数量。全部输入因已有输出被跳过时,不视为 API 翻译失败,而是提示删除同名文件或开启覆盖。
任务如何执行
状态与进度流
flowchart TD
Ready["就绪:无运行 worker"] --> Validate["检查输出目录、输入列表、API 和后台 future"]
Validate --> Scan["正在准备文件:FileScannerRunnable"]
Scan -->|扫描失败/无有效图片| FailedBefore["扫描失败或回到就绪"]
Scan --> Worker["正在翻译:TranslationRunnable"]
Worker --> Initial["current/total 初始进度"]
Initial --> Backend["后端进度 hook:批次结束/并发事件"]
Backend --> Progress["进度卡片 + StateManager 百分比 + 节流日志"]
Progress --> Backend
Backend -->|全部结果返回| Complete["任务完成:收集成功、失败、跳过"]
Worker -->|异常| Failed["任务失败:错误对话框 + 重置进度"]
Worker -->|用户停止| StopReq["停止中:失效回调、取消 task、清理临时资源"]
StopReq -->|future 和 cleanup 空闲| Stopped["任务已停止:重置进度并恢复开始按钮"]
Complete --> Reset["重置 0/0 进度;必要时刷新列表并询问打开编辑器"]
Reset --> Ready
进度计数会按跳过偏移修正当前数和总数,并把百分比限制在 0–100,同时更新主视图的进度条。并发模式和普通批处理都使用原始输入总数;特殊工作流会强制按非并发处理。
停止和资源边界
停止会先使回调失效,再请求 worker 取消;只有后台扫描、翻译和压缩包清理真正完成后,状态才切到“任务已停止”。是否卸载模型取决于 app.unload_models_after_translation。
任务限制
- 开始前依赖有效输出目录、非空输入列表、当前翻译器所需 API 凭据和没有未完成的前一任务收尾。
- 扫描阶段仍属于“正在翻译”状态,因此添加文件、添加文件夹、清空列表、文件列表和 API 管理页会被禁用。
- 停止与后台线程、asyncio task、压缩包临时目录和模型内存清理协作;强制终止进程可能留下部分输出或临时文件。
cli.overwrite=false时已有输出会计入进度但不处理;所有文件都跳过时任务会完成并提示覆盖设置,而不是调用翻译服务。batch_concurrent仅对正常工作流有效;导入 TXT/JSON、导出、仅上色、仅超分、仅修复和替换翻译会按串行处理。- 任务 ID 防止旧任务的延迟信号污染新任务,但不能撤销已落盘文件;需要由用户检查输出目录决定是否清理。
