用 PyInstaller 打包基于 PyQt 的程序遇到的坑

之前写了个脚本自己平常工作用,最近因为需要把脚本给其他同事用,为了避免它们还需要配置环境,于是用 PyQt 写了个界面,然后用 PyInstaller 打包成 exe 。打包过程中遇到了一些坑,纪录一下。

PyQt

之前写过一个虾米歌单导出小脚本,exe 版本是用的 Python 自带的 Tkinter 写的,所以这次尝试用 PyQt。写的时候遇到了任务栏闪烁和打包后程序界面图标不显示的问题。

  • 任务栏闪烁提示

    后台运行程序的时候,如果使用 QFileDialog ,程序弹出保存对话框的时候会在任务栏闪烁提示。但不是每个 Widget 都会有这个功能,但是这时候可以通过 QtWidgetactivateWindow()QApplication.alert() 来实现,但这两者使用的时候会有点区别。

    activateWindow() 是实例方法,只要程序窗口切换到前台被激活了就不会再闪烁。而 QApplication.alert(QWidget, msecs: int = 0) 是静态方法,msecs 值为 0 的时候,和 activateWindow() 的效果一致,但是需要在闪烁停了之后激活程序才会任务栏窗口颜色才会恢复正常,否则还是黄色,直到闪烁停了之后再激活一次程序。msecs 不为 0 的时候,超过这个时间后,任务栏窗口就会自动恢复正常。所以 activateWindow() 是比较好的选择,除非不要求一直在任务栏提示。

  • 资源文件在打包时的处理

    把代码用 PyInstaller 打包到一个文件的时候,会出现图标或图片都不显示的情况。这种时候就需要用 Qt’s resource system 来对其进行打包。

    首先新建一个 .qrc 文件,内容格式如下:

    <RCC>
      <qresource prefix="/" >
        <file>img/image1.png</file>
        <file>img/image2.png</file>
        <file>img/image3.png</file>
      </qresource>
    </RCC>
    

    然后去文件目录下执行 pyrcc5 -o images_qr.py images.qrc 命令,最后在代码中 import image_qr.py,并且修改下图片路径,一定要在路径前面加上冒号。

    import image_qr.py
    # your code
    self.setWindowIcon(QtGui.QIcon(':/img/image1.png'))
    

PyInstaller

之前用 cx_freeze 打过包,但感觉不理想,搜索了下发现 PyInstaller 用得比较多,就使用了这个,第一次用的时候没遇到问题,但是因为 Python 是装的 64 位的,所以打包之后的程序无法在 32 位的机器上使用。这就意味着我必须要在 Python 32 位的环境下打包,但重新配置了下环境之后,遇到了 ImportError 和无法链接到动态库的问题。

  • ImportError: DLL load failed

    用 PyInstaller 给程序打包的时候遇到了pyi_rth_qt5plugins returned -1 的 Fatal Error 提醒。这个错误信息几乎是毫无用处的,修改 .spec 文件,打开 debug 模式以及显示 console 后,在 running pyi_rth_qt5plugins.py 的时候发生了 ImportError: DLL load failed 找不到指定的模块 错误。

    回头想起了在编译的时候看到了很多 WARNNING 消息,回过头查看,发现了很多 lib not found 的问题。但是仔细检查了 Python 库之后,这些 DLL 明明在 C:\Python35-32\Lib\site-packages\PyQt5\Qt\bin 目录下,最后的搜索得到的解决办法是把这个目录添加到环境变量里。

    问题得到了解决,猜测原因是因为之前使用 pip 安装 PyQt 的时候, pypi.python.org 总是连接不顺畅,最后去下了个 .whl 文件直接安装,导致没有对应环境变量打包的时候找不到 DLL。

    # 环境: Python == 3.5.2 ,PyInstaller == 3.1.1
    
    10951 WARNING: lib not found: Qt5Svg.dll dependency of C:\python35-32\lib\site-packages\PyQt5\Qt\plugins\imageformats\qsvg.dll
    11206 WARNING: lib not found: Qt5Gui.dll dependency of C:\python35-32\lib\site-packages\PyQt5\Qt\plugins\imageformats\qsvg.dll
    11437 WARNING: lib not found: Qt5Core.dll dependency of C:\python35-32\lib\site-packages\PyQt5\Qt\plugins\imageformats\qsvg.dll
    11763 WARNING: lib not found: Qt5Gui.dll dependency of C:\python35-32\lib\site-packages\PyQt5\Qt\plugins\imageformats\qtga.dll
    12017 WARNING: lib not found: Qt5Core.dll dependency of C:\python35-32\lib\site-packages\PyQt5\Qt\plugins\imageformats\qtga.dll
    12224 WARNING: lib not found: Qt5Gui.dll dependency of C:\python35-32\lib\site-packages\PyQt5\Qt\plugins\platforms\qminimal.dll
    12418 WARNING: lib not found: Qt5Core.dll dependency of C:\python35-32\lib\site-packages\PyQt5\Qt\plugins\platforms\qminimal.dll
    12625 WARNING: lib not found: Qt5Gui.dll dependency of C:\python35-32\lib\site-packages\PyQt5\Qt\plugins\platforms\qwindows.dll
    12833 WARNING: lib not found: Qt5Core.dll dependency of C:\python35-32\lib\site-packages\PyQt5\Qt\plugins\platforms\qwindows.dll
    
  • api-ms-win-crt-runtime 错误

    PyInstaller 打包之后的程序运行的时候发生 api-ms-win-crt-runtime 动态库之类的错误,似乎只有在 Python 3.5 下打包才会遇到。因为 Universal CRT (KB2999226)缺失,可以通过安装此更新来解决问题。或者直接下载 Visual C++ Redistributable (x86 ,x64 )。

    参考链接:api-ms-win-crt-runtime-l1-1-0.dll is missing when open office file

这次的几个坑让我更坚定这类工具最好不要用最新版本,一不见得更稳定,二是遇到问题资料也比较少,在这类不必要的麻烦上花太多时间不值得,除非新版本能有很大的收益。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 155,541评论 4 358
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 65,987评论 1 285
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 105,387评论 0 236
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,325评论 0 201
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,657评论 3 284
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,125评论 1 202
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,519评论 2 305
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,242评论 0 193
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,863评论 1 234
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,198评论 2 239
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,747评论 1 255
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,106评论 2 249
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,635评论 3 227
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,926评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,631评论 0 190
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,131评论 2 261
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,083评论 2 257

推荐阅读更多精彩内容