首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >四轮重构、六个坑:一个离线文档工具的后半程复盘

四轮重构、六个坑:一个离线文档工具的后半程复盘

原创
作者头像
A1Book
修改于 2026-10-21 11:40:53
修改于 2026-10-21 11:40:53
770
举报

项目背景

手上有份复杂的中英文技术手册素材:587 篇文档的文字和图片都已收集齐,其中图片 265 张、原始体积 494 MB。

目标:做成离线桌面工具,中英对照、可检索、带图、单文件交付。

素材到手后的后半程——图片汇编、排版、图标、打包——实际折腾了四轮,踩了八个坑。这篇完整复盘。


一、后半程数据

阶段

耗时

产出

图片压缩

约 15 分钟

494 MB → 74.1 MB

界面开发

约 6 小时

检索 + 阅读 + 字号调节

图标制作

约 30 分钟

7 档尺寸 ico

打包调试

约 3 小时

107.7 MB 单文件 exe

问题排查

约 4 小时

修复 8 个问题

注意排查占比:接近三分之一。 这个比例值得注意——功能开发不是大头,问题排查才是。


二、图片压缩:三轮迭代才找对路

前两轮白干

轮次

策略

结果

压缩率

第一轮

PNG→WebP,限宽 1600

153.6 MB

31%

第二轮

限宽 1400,质量 75

140 MB

28.3%

第三轮

分布分析后统一 WebP

74.1 MB

15%

第三轮的关键动作是按格式统计体积:

代码语言:javascript
复制
.png     72 张    111.7 MB
.webp   191 张     11.4 MB
.gif      2 张     17.0 MB

72 张 PNG 占了 111.7 MB,而 191 张 WebP 才 11.4 MB。

问题不在参数,在于第一轮给带透明通道的图保留了 PNG。这些图绝大多数是界面截图,透明通道根本用不上。

统一转 WebP + 透明图铺白底 + 质量 78,最终 74.1 MB。

教训:优化前先做分布统计。前两轮调参的累计收益,不如第三轮改对格式。


三、排版:两个问题

问题一:右侧大片空白

工具做完自己用着挺顺,直到有人提了句"右边怎么空着"。

根因:换行宽度硬编码 880 像素。开发机 1080p 勉强够用,交付到高分屏(实际宽度 1596px)后只占 55%。

改成动态计算:

配合画布 resize 事件,批量同步所有文本控件。

问题二:修复时又翻车

第一版修复把字号比例也除进去了:

代码语言:javascript
复制
return max(320, int((w - 30) / sc))   # 错

逻辑是"字大了每行字数少,宽度应该小"。听起来合理,实际完全错误——换行宽度是像素单位,跟字号无关。

验证时发现:换行宽度 1740px,可视宽度 1596px,154 个控件溢出。

改成不除,验证通过:可视 1596px,换行 1566px,溢出 0 处。

教训:像素单位参数不要跟字号缩放联动。


四、最大的坑:图片全部看不见

现象

功能做完打包交付,用户反馈"看不到图片"。

排查过程

第一步:确认图片是否打包进去

用 PyInstaller 归档读取器检查,265 张全部在。排除打包问题。

第二步:最小复现

直接创建图片控件:

报错:

代码语言:javascript
复制
_tkinter.TclError: image "CTkImage object" doesn't exist

真凶:CTkImage 必须配 CTkLabel,不能塞给原生 tk.Label。

第三步:为什么用户看不到报错

翻代码发现:

异常被静默吞掉了。

修复

改完验证:11 张图片控件全部成功创建。

教训:GUI 开发里 except: pass 是最危险的一行代码。它让程序表面正常、功能全废,排查成本极高。


五、其他几个坑

坑一:图片映射表被覆盖

压缩脚本把 URL → 文件名 的映射错误写成了 文件名 → 文件名,265 条全部失配。

表现是图片明明在,但渲染时找不到。

修复:重建映射,链式转换。

坑二:打包路径漂移

报错:

代码语言:javascript
复制
ERROR: Script file 'app\main.py' does not exist.

文件明明在。查了半天发现工作目录漂移了——之前某脚本调了 os.chdir(),目录跑到了子目录。

改成全用绝对路径。

排查技巧:打包脚本第一行打印 os.getcwd()。

坑三:诊断进程卡死

为了排查问题,打包了一个 --console 诊断版。结果它卡住不退出,占满执行通道,只能手动结束进程。

教训:诊断工具也要设超时,别让它无限等待。

坑四:桌面图标不更新

exe 图标已经换成新的,但桌面显示还是旧的。

原因:Windows 图标缓存。

解决:ie4uinit.exe -show 刷新,或重启资源管理器,或换个文件夹路径验证。

坑五:测试污染配置

验证脚本把字号改成 90% 写进了用户配置文件,影响真实使用。

修复:重置配置,测试脚本改用独立配置路径。


六、图标制作

源图是一张竖版长图(1440×2880),中间有一枚圆形花卉徽章。

定位

先用视觉模型估算位置:Y 41%-58.5%,X 430-1010。

精修

程序按背景色差找精确包围盒:

加 16% 呼吸空间,居中裁切。

输出

1024×1024 圆角方形,7 档尺寸(16/24/32/48/64/128/256),168 KB。


七、最终成果

项目

数值

图片

265 张,74.1 MB,点击放大

排版

自适应,窗口拉伸实时跟随

字号

8 档(80%-200%),设置持久化

图标

7 档尺寸,文件/标题栏/封皮统一

体积

107.7 MB 单文件

运行

完全离线


八、复盘:哪些做对了,哪些可以更好

做对的

第一,优化前先统计。 图片压缩第三轮改对了格式,效果远超前两轮调参。

第二,问题留记录。 每个坑都记了原因和改法,这篇复盘就是这么来的。

第三,验证用数据说话。 排版修复后实测可视宽 1596、换行宽 1566、溢出 0,不凭印象判定。

可以更好的

第一,测试覆盖不足。 图片显示问题如果早期有渲染测试,交付前就能发现,不用等用户反馈。

第二,异常处理太随意。 except: pass 是坏习惯,应该从代码规范层面禁止。

第三,配置隔离没做。 测试脚本污染生产配置,说明测试环境隔离没设计好。

第四,诊断工具没设超时。 卡死占通道,浪费了不少时间。


九、给同类项目的建议

技术选型

  • 图片:Pillow,统一 WebP,先统计分布再定策略
  • 界面:CustomTkinter,注意 CTkImage 配 CTkLabel
  • 打包:PyInstaller --onefile --windowed,全用绝对路径

流程建议

  1. 图片汇编,先统计分布再压缩
  2. 做最小界面,能看能翻
  3. 加图片显示,注意对象生命周期
  4. 打磨排版,自适应 + 字号调节
  5. 图标与视觉统一
  6. 打包,断网测试 + 冒烟验证

时间预估

  • 熟悉流程:半天到一天
  • 第一次做:2-3 天
  • 排查问题:预留 30% 时间

结语

后半程四轮重构,六个坑。

工具本身不复杂,但每个环节都有细节:图片要瘦身、排版要自适应、打包要能跑,关关都要过。

最有价值的不是这个工具,而是这份踩坑记录。真正解决问题的还是逐条定位、实测确认的笨办法。

如果这篇复盘对你有帮助,欢迎交流。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 项目背景
    • 一、后半程数据
    • 二、图片压缩:三轮迭代才找对路
      • 前两轮白干
    • 三、排版:两个问题
      • 问题一:右侧大片空白
      • 问题二:修复时又翻车
    • 四、最大的坑:图片全部看不见
      • 现象
      • 排查过程
      • 修复
    • 五、其他几个坑
      • 坑一:图片映射表被覆盖
      • 坑二:打包路径漂移
      • 坑三:诊断进程卡死
      • 坑四:桌面图标不更新
      • 坑五:测试污染配置
    • 六、图标制作
      • 定位
      • 精修
      • 输出
    • 七、最终成果
    • 八、复盘:哪些做对了,哪些可以更好
      • 做对的
      • 可以更好的
    • 九、给同类项目的建议
      • 技术选型
      • 流程建议
      • 时间预估
    • 结语
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档