在 Windows 下开发的 Python 程序可以通过 pyinstaller 来打包。在 Mac 下可以使用 py2app 来打包 Python 程序。
生成程序图标
Mac 下程序图标扩展名是 icns,Mac 下自带有程序能够生成这种类型的图标。假设我们有一个 png 图像想要制作为 Python 程序的图标,那么我们可以使用如下的程序 icon.py
生成:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
|
"""生成应用程序图标""" import os from datetime import datetime
def icons(img_path, icon_name, save_path='.'): """ 通过Mac自带命令生成Python程序图标 :param img_path: PNG图像地址 :param icon_name: 图标名称 :param save_path: 图标保存路径 :return: icns 图标 """ tmp_iconset = os.path.join(os.path.dirname(img_path), datetime.now().strftime("%Y%m%d.%H%M%S_") + "tmp.iconset") os.makedirs(tmp_iconset) sizes = [2 ** x for x in range(4, 10)] for size in sizes: tmp_icon_name = f"icon_{size}x{size}.{os.path.splitext(img_path)[-1][1:]}" cmd = f"sips -z {size} {size} {img_path} --out {os.path.join(tmp_iconset, tmp_icon_name)}" os.system(cmd) tmp_icon_name2 = f"icon_{size}x{size}@2x.{os.path.splitext(img_path)[-1][1:]}" cmd2 = f"sips -z {size * 2} {size * 2} {img_path} --out {os.path.join(tmp_iconset, tmp_icon_name2)}" os.system(cmd2) save_icon = icon_name + '.icns' cmd_icns = f"iconutil -c icns {tmp_iconset} -o {os.path.join(save_path, save_icon)}" os.system(cmd_icns)
if __name__ == "__main__": img_path = './resources/assets/cell.png' icons(img_path=img_path, icon_name='Icon', save_path='./resources/assets')
|
程序 icon.py
运行成功后,在目录 save_path
下会生成 Icon.icns
程序图标文件。
py2app 打包程序
安装 py2app
生成 setup.py
进入项目主目录,假设程序的入口函数是 XImage.py
,那么运行如下命令
1
| py2applet --make-setup XImage.py
|
此时,会在项目主目录生成 setup.py
文件。编写 setup.py
,增加图标内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| """ This is a setup.py script generated by py2applet
Usage: python setup.py py2app """
from setuptools import setup
APP = ['XImage.py'] DATA_FILES = [] OPTIONS = {'iconfile': './resources/assets/Icon.icns', 'resources': ['resources'], 'plist': {'CFBundleShortVersionString': '0.04'}, "packages": ["PIL", ]}
setup( app=APP, data_files=DATA_FILES, options={'py2app': OPTIONS}, setup_requires=['py2app'], )
|
注意:
- 在使用 PyQt5 编写 Python GUI 程序时,可能需要增加上
import matplotlib.backends.backend_tkagg
,但是在 Mac 打包时须要注销掉;
- Mac 中字体选择系统有的,不要选没有的,我的是在 Windows 上开发,拷贝到 Mac 打包,出现宋体错误,需要在 QtDesigner 中取消掉所有宋体。
清理构建目录
构建程序
1 2 3 4
| python setup.py py2app -A
python setup.py py2app
|
此时,就在主目录下的 dist
里面包含有 XImage.app
的应用程序。
问题
出现运行问题,可以在命令行输入如下内容调试,可以看到错误提示:
1 2 3 4
| cd /Users/jinzhongxu/projects/image0.04/image
dist/XImage.app/Contents/MacOS/XImage
|
实际打包时,运行程序出现 libffi.8.dylib
找不到,因此,需要把本机中的 libffi.8.dylib
拷贝到打包后的程序中。
1 2 3 4 5 6 7
| sudo -i find / -name "libffi.8.dylib" -type f
cd /Users/jinzhongxu/projects/image0.04/image
cp /usr/local/Cellar/libffi/3.4.3/lib/libffi.8.dylib dist/XImage.app/Contents/Frameworks/libffi.8.dylib
|
pyinstaller 打包程序
不需要手动创建并编辑 setup.py 文件,使用类似下面的程序即可打包
1 2 3 4 5 6 7 8 9
|
import os
if __name__ == '__main__': cmd = "pyinstaller XImage.py -w --clean -i resources/assets/Icon.icns --distpath release0.06" \ " --add-data resources:resources" os.system(cmd)
|
注意:如果程序中使用了多进程 multiprocessing,则需要则主程序中增加如下内容:
1 2 3 4 5 6 7 8 9 10
| import multiprocessing
if __name__ == '__main__': multiprocessing.freeze_support() app = QtWidgets.QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec())
|
参考文献
- py2app 2.0a0 documentation
- Mac 系统使用 iconutil 生成 App 图标
- 快速生成 Mac App icns 图标
- 知识储备 – 用py2app将Python代码打包成MacOS可用的APP
- py2app-python打包工具