4

Mac 下打包 Python 程序

 1 year ago
source link: https://xujinzh.github.io/2023/04/12/mac-convert-python-to-macosx-app/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Mac 下打包 Python 程序

发表于2023-04-12|更新于2023-04-17|technologymac
字数总计:1.1k|阅读时长:4分钟|阅读量:10

在 Windows 下开发的 Python 程序可以通过 pyinstaller 来打包。在 Mac 下可以使用 py2app 来打包 Python 程序。

生成程序图标

Mac 下程序图标扩展名是 icns,Mac 下自带有程序能够生成这种类型的图标。假设我们有一个 png 图像想要制作为 Python 程序的图标,那么我们可以使用如下的程序 icon.py 生成:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Author : Jinzhong Xu
# @Contact : [email protected]
# @Time : 2023/4/12 21:41
# @File : icon.py
# @Software : PyCharm

"""生成应用程序图标"""
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

pip install py2app

生成 setup.py

进入项目主目录,假设程序的入口函数是 XImage.py,那么运行如下命令

py2applet --make-setup XImage.py

此时,会在项目主目录生成 setup.py 文件。编写 setup.py,增加图标内容:

"""
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", ]} # 手动指定需要打包进程序的第三方Python包,PIL默认不能自动打包进去

setup(
app=APP,
data_files=DATA_FILES,
options={'py2app': OPTIONS},
setup_requires=['py2app'],
)

注意:

  1. 在使用 PyQt5 编写 Python GUI 程序时,可能需要增加上 import matplotlib.backends.backend_tkagg,但是在 Mac 打包时须要注销掉;
  2. Mac 中字体选择系统有的,不要选没有的,我的是在 Windows 上开发,拷贝到 Mac 打包,出现宋体错误,需要在 QtDesigner 中取消掉所有宋体。

清理构建目录

rm -rf build dist
# 别名模式,本地测试使用。没有将完整的 python 环境、第三方库打包到 app 中。运行程序完全依赖该电脑的 python 环境和第三方库
python setup.py py2app -A
# 把程序依赖的 python 环境、第三方库都打包进程序,一般将程序放在其他的mac电脑中,可直接运行
python setup.py py2app

此时,就在主目录下的 dist 里面包含有 XImage.app 的应用程序。

出现运行问题,可以在命令行输入如下内容调试,可以看到错误提示:

# 进入项目主目录
cd /Users/jinzhongxu/projects/image0.04/image
# 打开打包后的程序,我这里程序名为 XImage
dist/XImage.app/Contents/MacOS/XImage

实际打包时,运行程序出现 libffi.8.dylib 找不到,因此,需要把本机中的 libffi.8.dylib 拷贝到打包后的程序中。

# 先从本机寻找 libffi.8.dylib
sudo -i
find / -name "libffi.8.dylib" -type f
# 进入项目主目录
cd /Users/jinzhongxu/projects/image0.04/image
# 拷贝本机的 libffi.8.dylib 到打包后的程序中
cp /usr/local/Cellar/libffi/3.4.3/lib/libffi.8.dylib dist/XImage.app/Contents/Frameworks/libffi.8.dylib

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK