苹果系统打包pyqt/side6程序为可执行app并构建dmg
Windows下打包比较简单,pyinstaller -w start.py
一条执行完毕就ok了,MacOS下略复杂。记述下,以便后续复盘。
前提:当然要安装好python3环境,使用
brew install python@3.10
安装执行
export PATH="/usr/local/opt/python@3.10/bin:$PATH"
和
source ~/.bash_profile && source ~/.zshrc
设python3.10为默认python
创建python虚拟环境
先创建个空白文件夹,比如 py
,然后进入文件夹,打开终端,执行命令python3 -m venv venv
,执行完毕后目录内多出一个 venv 文件夹,执行在终端中执行source ./venv/bin/activate
激活该虚拟环境,激活成功后,终端最前方提示符会变为 (venv)
安装pyside6 pyinstaller
继续终端中执行 pip install pyside6 pyinstaller
创建py文件 app.py
app.py中输入以下代码
# -*- coding: utf-8 -*-
import sys
from PySide6 import QtWidgets
from PySide6.QtCore import Qt, QPoint
from PySide6.QtGui import QGuiApplication
class StartWindow(QtWidgets.QWidget):
def __init__(self):
super(StartWindow, self).__init__()
self.width = 1200
self.height = 700
v1 = QtWidgets.QVBoxLayout()
v1.addStretch(1)
h1 = QtWidgets.QHBoxLayout()
v1.addLayout(h1)
v1.addStretch(1)
h1.addStretch(1)
self.lab = QtWidgets.QLabel()
self.lab.setText(f"你好啊,这是一个pySide6窗口")
self.lab.setStyleSheet("""font-size:16px;color:#f00;text-align:center""")
h1.addWidget(self.lab)
h1.addStretch(1)
self.setLayout(v1)
# 窗口大小
self.resize(560, 350)
self.show()
self.center()
def center(self):
screen = QGuiApplication.primaryScreen()
screen_resolution = screen.geometry()
self.width, self.height = screen_resolution.width(), screen_resolution.height()
self.move( QPoint( int( (self.width - 560) / 2), int( (self.height - 350)/ 2 ) ) )
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
try:
startwin = StartWindow()
except Exception as e:
print(f"error:{str(e)}")
sys.exit(app.exec())
如果没错的话,现在你能看到一个窗口
将这个程序使用pyinstaller打包
继续前边的终端,确认提示符是否含有(venv)
输入打包指令pyinstaller --windowed app.py
--windowed 是禁止显示控制台参数,如果不添加,打开后会显示一个黑色终端窗口
等待执行结束。
在当前目录下会多出2个文件夹 dist
和 build
,其中build
可以忽略,重点关注dist
这是打包后的执行文件所在目录。
└── dist
├── app
│ ├── libcrypto.1.1.dylib
│ ├── PySide6
│ ...
│ ├── app
│ └── Qt5Core
└── app.app
如上图所示,dist/app.app
就是mac上的可执行程序,双击应该能看到和上方一样的pyside6窗口。
dist/app
则是一个文件夹,里面是封装好的所有依赖.目前可以忽略它
复制数据目录和资源文件
一般程序都会有额外的资源需要包含进去,比如图标、ini配置文件
假如这个程序里 app.py
同目录下还有1个文件夹 data
需要整个复制,有一个图标 icon.ico 文件也需要复制,那么将打包命令调整为
pyinstaller --windowed --add-data="data:data" --add-data="icon.ico:icon.ico" app.py
--add-data=
代表数据复制指令,格式为 --add-data=“原始资源目录或文件:要复制到目录或文件”
,其中目标目录是相对于打包后的程序根目录。
导入额外包
一般情况下 pyinstaller 自动分析依赖并将用到的包都打包进去,但有时可能会丢失某些依赖包,这时执行打包后的程序会提示“not found module”错误。
在打包时,使用--hide-import=包名
指令列出要额外包含进的包,即可解决该问题。
比如我用到了 faster-whisper
和pytz
包,打包后提示缺少,那么重新修改下打包命令,将这2个包包含进入,打包命令更新为
pyinstaller --windowed --hidden-import=faster-whisper --hidden-import=pytz app.py
构建 dmg 磁盘映像
在Windows下,直接将打包后的 dist/app
文件夹压缩为zip,分发即可。
但在苹果系统下, app.app
是可执行的程序,但本质也是一个文件夹,改为zip扩展后发送给用户,再让用户改为app后缀,其实也是可以的,但显然不符合macos逻辑。正确的方法应该是构建一个dmg映像。
先将 dist 目录下的 app文件夹 删掉,只保留 app.app 可执行程序。
接着执行brew install create-dmg
安装 create-dmg 工具.
安装成功后,终端执行构建命令
create-dmg
--volname "app"
--window-pos 200 120
--window-size 600 300
--hide-extension "app.app"
--app-drop-link 425 120
"app.dmg"
"dist/"
如果未报错的话,执行后,将在 app.py 同目录内看到一个名为 app.dmg
的文件。
双击则可安装,然后就能在启动中心看到该程序了。
更多pyinstaller打包用法
转载自:https://juejin.cn/post/7362725616569171983