PyInstaller 打包单文件 exe 注意事项 0. 官网1. PyInstaller 打包单文件 exe 时遇到的问题2. 找不到 PyQt5.sip 的解决方案3. 找不到窗体小图标的解决方案4. 找不到 ffprobe.exe 的解决方案5. 使用 subprocess.Popen 无法调用外部程序的解决方案
我写了一个 Python 小脚本,用来统计当前目录及其子目录下所有视频文件个数与时长,其中用到了 subprocess.Popen 调用了外部 exe 文件 ffprobe.exe ,另外使用 PyQt5 创建了一个简单的小窗体,在窗体标题显示程序图标,源码执行效果如下:
然而在用 PyInstaller 打包成单文件 exe 的时候先后遇到了以下四个问题:
找不到 PyQt5.sip找不到窗体小图标找不到 ffprobe.exe脚本正常运行,调用 ffprobe.exe 出错以下是针对各个问题的解决方案,其中一些问题有多个解决方案,这里仅提供一种,仅供参考。
这个问题应该是 PyInstaller 没有导入该模块导致的,在源代码中显式导入即可:
from PyQt5 import sip 1参考网址:https://blog.csdn.net/yueguangmanong/article/details/81139224
找不到窗体小图标的原因是,单文件打包的时候, PyInstaller 改变了资源存储路径,用原来的相对路径引用不到。
所以首先在源代码中加入 resource_path 函数,该函数返回资源的绝对路径:
def resource_path(relative_path): '''返回资源绝对路径。''' if hasattr(sys, '_MEIPASS'): # PyInstaller会创建临时文件夹temp # 并把路径存储在_MEIPASS中 base_path = sys._MEIPASS else: base_path = os.path.abspath('.') return os.path.join(base_path, relative_path)然后把所有对资源相对路径的引用传入 resource_path 函数即可,比如:self.setWindowIcon(QIcon(resource_path(r'img\电影.png')))
最后一步,在使用 pyinstaller 命令生成 exe 的时候要使用 --add-data 选项加入所有资源文件。 在 Windows 下该选项的格式为 --add-data="源地址;目标地址" ,可多次重复使用。 其他系统的命令格式需要把地址分隔符从分号 ; 改成冒号 : ,详见官方手册。pyinstaller --add-data="img\电影.png;img" --add-data="ffprobe.exe;." -i="img\电影.ico" -Fw movielen.py
该问题的产生原因,跟找不到窗体小图标是一样的,所以解决方案也一样。 同样注意,最后使用 pyinstaller 命令的时候需要用 --add-data 选项把 ffprobe.exe 添加进去。 另外,还可以通过编写 spec 配置文件来做到这一点,具体使用方法请查阅官方手册。
在我的脚本中,通过 subprocess.Popen 来调用了外部可执行文件 ffprobe.exe ,但是打包成单文件 exe 就运行失败。 原因在于,我在打包过程中使用了 -w 选项,即无控制台模式,这时就需要修改源码,显式指定 subprocess.Popen 的 stdin 、 stdout 和 stderr 参数。 源码修改如下:sp = subprocess.Popen(cmd, stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.STDOUT, shell = True)
最终使用以下命令,成功打包了单文件 exe (无控制台模式),并且拥有自己的图标,图片资源完美显示,可以封装并调用别的 exe 文件。pyinstaller --add-data="img\电影.png;img" --add-data="ffprobe.exe;." -i="img\电影.ico" -Fw movielen.py
最终效果如下:
参考网址:https://github.com/pyinstaller/pyinstaller/issues/1339