cx_Freeze 打包 Python3.4+PyQt5.3
基于 Python 打包成 exe 的工具,主要有这样几个:
但遗憾的是,目前只有 cx-Freeze 明确表示支持 Python3 。pyinstaller 则有一个试验性分支在进行这方面的测试。
我有一个项目 data_tester
使用 Python3.4+PyQt5.3 开发,需要使用 cx-Freeze 将其打包成 exe 格式,提供给其它同事在 Windows 7(64bit) 系统中使用。
具体打包的方法,查看 cx-Freeze 官方文档 即可知晓,这篇文章中仅仅记述我踩过的几个坑。
_fix_up_module
打包成功后,运行出现这样的错误:
这是因为,在 PiPy 上安装的 cx-Freeze 有问题 。需要在 这里下载一个独立的 Windows 编译版本 进行安装。
由于我们使用的是 64bit 系统,我下载的是 cx_Freeze‑4.3.3.win‑amd64‑py3.4.exe
,双击安装即可。注意安装前先卸载在 PyPi 上安装的 cx-Freeze 包。
No such file or directory
使用 exe 版本的 cx-Freeze
打包成功后,运行时又出现新的错误:
在程序中,我们经常需要获取项目所在的当前路径,用来读取一些配置文件或资源。
在 data_tester
中,我需要读取一个位于 hhl
包中的 dt.conf
资源文件。下面是读取代码:
:::python
workDir = os.path.abspath(os.path.join(
os.path.split(os.path.abspath(__file__))[0], os.pardir))
templFile = os.path.join(workDir, 'hhl', 'dt.conf')
而在 exe 版本中,由于所有的 python 代码都被打包到 library.zip
文件中了,__file__
的值就变成了 library.zip
中的相关路径。这样去取一个资源文件,显然是取不到的。
还有一个问题,就是 cx-Freeze
并不会将非 python 文件自动打包到最终的 exe 所在的文件夹中。我们需要在 setup.py
中指定我们需要打包的资源文件。这些指定的文件会被直接复制到 exe 所在的文件夹中,而不会被打包到 library.zip
中。
:::python
options = {
'build_exe':{'packages':packages, 'include_files':['hhl/dt.conf']},
}
这样进行处理之后,dt.conf
这个资源文件在 exe 版本中的路径和非 exe 版本中的路径就不同了。我们需要判断当前执行的是否是 exe 版本,根据结果来读取不同路径的 dt.conf
。
下面的代码进行了这样的处理:
#!/usr/bin/env python
# 当位于 exe 版本中时,可以使用 os.sys.executable 来获取当前执行文件的路径
if hasattr(sys, 'frozen'):
workDir = os.path.dirname(os.path.join(os.sys.executable))
templFile = os.path.join(workDir, 'dt.conf')
else:
workDir = os.path.abspath(os.path.join(
os.path.split(os.path.abspath(__file__))[0], os.pardir))
templFile = os.path.join(workDir, 'hhl', 'dt.conf')
这是完整的 setup.py
文件:
#!/usr/bin/env python
import sys
from cx_Freeze import setup, Executable
base = None
if sys.platform == 'win32':
base = 'Win32GUI'
packages = [
'hhl',
'hhl.protos',
'hhl.components',
'hhl.libs.helper',
'hhl.libs.net',
]
options = {
'build_exe':{'packages':packages, 'include_files':['hhl/dt.conf']},
}
executables = [Executable('main.py', base=base, targetName='datatester.exe')]
setup(
name="datatester",
version="1.0.0",
url='http://zengrong.net/',
author='zrong',
author_email='zrongzrong@gmail.com',
description="A data tester for HHL.",
options=options,
executables=executables,
)
Could not load the Qt platform plugin "windows"
经历了上面两个坑,在打包的电脑上,运行成功了。但是把打包结果复制到其它电脑上运行时,出现了这样的错误:
python 3.3, pyqt5 and cx_freeze exe on 64-bit windows 一文中提到,将 libEGL.dll 复制到 exe 相同目录可以解决这个问题。这个文件可以在 PyQt5 的安装文件夹中找到。
- 文章ID:2207
- 原文作者:zrong
- 原文链接:https://blog.zengrong.net/post/cx_freeze-package-python34-and-pyqt53/
- 版权声明:本作品采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可,非商业转载请注明出处(原文作者,原文链接),商业转载请联系作者获得授权。