如何从具有 PySide2 GUI 的 python 脚本构建一个 mac os 应用程序?
Posted
技术标签:
【中文标题】如何从具有 PySide2 GUI 的 python 脚本构建一个 mac os 应用程序?【英文标题】:How to build an mac os app from a python script having a PySide2 GUI? 【发布时间】:2021-01-21 10:52:46 【问题描述】:上下文:
我正在使用 PySide2 GUI 开发一个简单的 Python 应用程序。它目前在 Windows、Linux 和 Mac 上运行良好。在 Windows 上,我可以使用 PyInstaller 和 InnoSetup 来构建一个简单的安装程序。然后我尝试在 Mac 上做同样的事情。它很快就坏了,因为系统拒绝启动命令或 PyInstaller 生成的应用程序,因为它没有正确签名。因为我不是苹果开发者,所以我不能签署任何东西......
经过一番研究,我尝试了 py2app。我可以在这里更进一步。与
python setup.py py2app -A
我可以创建一个可运行的应用程序。这显然不能移植到不同的系统,因为它使用我的开发文件夹。如果我使用python setup.py py2app
,生成的程序将无法启动,因为 py2app 没有复制所有必需的 Qt 内容。我尝试将丢失的库一个一个添加,但最终系统找不到插件,我放弃了...
问题:
有人可以帮助我使用 Qt GUI 将 python 脚本或包转换为 Mac 上的便携式应用程序吗?理想情况下,配方应该说明如何使用自定义应用程序图标,但这不是必需的。
参考资料:
Python 3.8.5 macOS 10.15.7 Catalina PySide2 5.15.1 PyInstaller 4.0 py2app 0.22由于我的真实包对于 SO 问题来说太大了,我将其缩减为一个最小的可重现示例:
from PySide3.QtWidgets import *
import sys
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
hello = QLabel('Hello', self)
hello.move(50, 50)
def run(args):
app = QApplication(args)
main = MainWindow()
main.show()
sys.exit(app.exec_())
if __name__ == '__main__':
run(sys.argv)
这里是用于 py2app 的 setup.py 文件:
from setuptools import setup
APP = ['app.py']
DATA_FILES = []
OPTIONS =
setup(
app=APP,
data_files=DATA_FILES,
options='py2app': OPTIONS,
setup_requires=['py2app'],
)
【问题讨论】:
setup.py 中有一个错字导致它无法运行 你可以看看这个medium.com/python-pandemonium/… 也看看learnpyqt.com/pyside2-book @anon01:我的错。我通常复制和粘贴代码以避免拼写错误,但在这里我不能。 learnpyqt.com/courses/packaging-and-distribution/… 这会有所帮助 【参考方案1】:我认为您缺少的是将 Python3 框架包含在您的应用程序包中。我最近自己开发了一个简单的 macOS 应用程序,但是我想对如何做有更多的了解,所以我对应用程序的实际结构做了一些研究。基本上,您将把所有内容放入一个带有应用程序名称的普通文件夹中。调用此文件夹MyApp
。在这个文件夹中,我们将有另一个名为Contents
。据我了解,py2app
只是获取构成您应用程序的所有内容,并将它们构建在此文件夹中,并创建一个 Info.plist
文件,该文件也位于 Contents
内部。到目前为止,这是你所拥有的:
MyApp
-> Contents
-> -> Info.plist
除了包含所有必需的properties 的Info.plist
文件之外,在您的Contents
文件夹中,您将至少有一个MacOS
文件夹和一个Resources
文件夹。您的问题是您还需要一个 Frameworks
文件夹,您可以在其中添加所需的 Python 版本。
现在,您的应用层次结构应如下所示:
MyApp
-> Contents
-> -> Info.plist
-> -> MacOS
-> -> Resources
-> -> Frameworks
在Frameworks
文件夹中,您可以放置用于构建应用程序的完整 Python 3 框架,以及运行应用程序所需的任何站点包,然后您可以反映所有可执行文件中的这些更改,以便您指向正确的安装。
据我了解,使应用程序在 MacOS 上正常运行所需要做的就是确保您的主要可执行文件位于 MacOS
文件夹中,并指向位于 Frameworks
文件夹中的 Python,您的图标 .icns
文件被放置在Resources
文件夹中,您的Info.plist
文件被构建。
为了让 MacOS 将其识别为完整的应用程序,我相信您可能需要使用 productbuild
并包含开发人员许可证书,但只有在您希望分发应用程序时才真正需要。否则,我只是将扩展名.app
添加到MyApp
,将其转换为应用程序。
如果没有上述许可证/证书,它可能无法识别它应该找到您的图标文件并添加它,因此如果您在预览中打开它,全选并复制它,您应该可以右键单击应用程序,按“获取信息”,然后将图标粘贴到窗口中当前图标的顶部以使其正确显示。
编辑:我用于学习制作 macOS 应用程序的资源:
Bundle structure
Including frameworks
Signing your application
productbuild
manpage
【讨论】:
感谢您的回答。它有助于了解哪些 macOS 应用程序在后台。包含框架的要点可能是手动构建应用程序的一种可能方式。我还暗示了一个与 python 链接来调用我自己的 PySide2 代码的本机/C 应用程序应该可以工作。如果我不能让 py2app 完成这项工作,我会试一试(如果我不使用 PySide2 会做什么......) @SergeBallesta PySide2 只是 GUI 包。即使我使用 Tkinter 构建了我的应用程序,同样的原则仍然有效。与在计算机上查找包相比,您可以做的是将一个 Python 版本传输到 Frameworks 文件夹(用于在应用程序之外制作程序的任何版本的副本),然后调用它Python 的 pip 安装程序,用于下载 PySide 和 Qt。我相信这将确保它们安装在您的应用程序中。只需使用path/to/app/python3 -m pip install PySide2 PyQt5
【参考方案2】:
我认为您的问题的解决方案可以在here 找到。首先,创建a virtual environment,并将所有模块安装到同一个虚拟环境中。
mkvirtualenv --python="PATH/TO/PYTHON3.6.5/python.exe" venv
安装Qt
框架
# Install qt via homebrew
brew install qt
# Switch to version 5.11.1
brew switch qt 5.11.1
# Do this to link qmake with qt
brew link qt5 --force
然后,安装 PySide2
git clone --recursive https://code.qt.io/pyside/pyside-setup
之后,
cd pyside-setup && git checkout 5.11
构建并安装PySide2
,并确保设置Qt
安装附带的QMAKE
路径
#To get the path
which qmake
# Make sure that your virtual environment is activated
# Build PySide2 from source
python setup.py install --qmake=<PATH/TO/QMAKE> --build-tests --ignore-git --jobs=8
# Install PySide2
python setup.py build --qmake=/path/to/qmake --build-tests --ignore-git --jobs=8
更新
首先,确保您在相同的虚拟环境中运行您的代码,并将其转换为标准的 Mac OS 应用程序,您可以使用 py2app 或 pyinstaller 。另外,如果您的 py2app 在您执行相同的过程后无法与您当前的版本一起使用,请尝试降级。
sudo easy_install py2app
#or
pip install -U git+https://github.com/metachris/py2app.git@master
创建 setup.py
py2applet --make-setup app.py
Wrote setup.py
您必须创建 a config file 或 see this example 并包含您拥有的任何文件
from setuptools import setup
APP = ['app.py']
DATA_FILES = []
OPTIONS =
'argv_emulation': True,
'iconfile': 'app.icns'
setup(
app=APP,
data_files=DATA_FILES,
options='py2app': OPTIONS,
setup_requires=['py2app'],
)
要构建应用程序使用
python setup.py py2app -A
要运行应用程序,您必须使用这种方式
./dist/app.app/Contents/MacOS/app
如果它与python setup.py py2app -A
一起使用,则表示一切正常,您需要使用
rm -rf build dist
python setup.py py2app
如果出现任何问题,请参阅这些参考资料1、2 和 3。此外,还有alternatives ways 可以将您的应用程序转换为操作系统。
阅读您的评论后,我尝试查看问题所在,发现this 可能会解决问题,或者您可以使用替代工具,例如bbFreeze
、pyInstaller
或cx_Freeze
【讨论】:
感谢您的回答,但它是关于使 PySide2 在 macOS 上可用。这部分有效,如果我使用python3 app.py
它运行良好。我的问题是我想将它转换为标准的 macOS 应用程序,同样我可以使用 PyInstaller 和 InnoSetup 为 Windows 构建一个可安装的独立程序。
@SergeBallesta 我已经更新了答案,并确保您在相同的虚拟环境中运行代码。
我已经可以使用python setup.py py2app -A
。当我删除 -A
以尝试构建 独立 应用程序时出现问题。
你用的是同一个环境吗?如果是这样,请尝试使用可以在答案中找到的替代工具,例如pyInstaller
或cx_Freeze
。见docs.python-guide.org/shipping/freezing
我想要的是一个包含所有相关版本的工作环境示例,如果可能的话,还有一个在 macOS Catalina 上测试过的示例。【参考方案3】:
我已经使用fbs 成功构建了应用程序。 它旨在构建 Python+PyQt5 应用程序(您也可以使用 PySide2),它也应该可以在 Mac OS 上运行(根据文档/教程)。
使用 PyInstaller 包含 PyQt5 依赖项时经常失败(尤其是当我使用 pyqtgraph
时),但使用 fbs 时效果很好。
【讨论】:
您能否确认您能够在 macos Catalina 上成功运行链接教程?在我的系统上,命令fbs run
正确显示了一个漂亮的窗口,但fbs freeze
与7136 ERROR: Can not find path ./libshiboken2.abi...
中断【参考方案4】:
如果你想为 OSX 打包,你应该要么
创建一个 Brew Tap
这对于开源开发人员来说可能是最有意义的
一般说明https://docs.brew.sh/How-to-Create-and-Maintain-a-Tap
在 git 中托管您的代码(不需要是 GitHub) 创建公式 (Formula Cookbook) 在 GitHub 上 fork homebrew-core 添加您的公式并创建拉取请求以将其放入主存储库 支持您的拉取请求,使其完成加入 Apple 开发者计划
这对于闭源开发者来说可能是最有意义的
概述:https://developer.apple.com/programs/how-it-works/
该计划每年花费 99 美元,但允许您签署您的软件包/最终二进制文件并自行分发或在他们的 App Store 上分发
创建帐户后,以下是 OSX 打包和签名指南https://developer.apple.com/forums/thread/128166
构建您的代码以支持签名(添加构建步骤以将您的工作复制到干净的路径以避免令人沮丧的返工)% codesign -s <Developer ID Application signing identity> /path/to/code
选择一种存储格式(.zip
、.dmg
、.pkg
)并将您的应用程序捆绑在一起
【讨论】:
感谢您提供有关如何为 macOS 构建应用程序的一般信息。 brew 部分可能会有所帮助。但我目前的问题集中在 Qt for Python (PySide2) 应用程序上,你的答案并没有真正解决。 @SergeBallesta '希望对后来的用户有所帮助!看起来您的 Qt 部分通过安装程序运行良好,但您正在反对自己签名或跳过安装程序并将依赖项管理移动到上游。【参考方案5】:要求
适用于 Python 3.8.5 macOS 10.15.7 Catalina 使用 PySide2 和 py2app问题
PySide2
必须在 OPTIONS 下添加到包列表中
运行应用程序时仍然出现错误:Library not loaded: @rpath/libshiboken2.abi3.5.15.dylib, Reason: image not found
解决方案
稍加修改的 setup.py 可能如下所示:
from setuptools import setup
APP = ['app.py']
DATA_FILES = []
OPTIONS =
'packages': ['PySide2'],
'iconfile': 'some_icon.icns',
'plist':
'CFBundleDevelopmentRegion': 'English',
'CFBundleIdentifier': "com.ballesta.xxx",
'CFBundleVersion': "1.0.0",
'NSHumanReadableCopyright': u"Copyright © 2020, Serge Ballesta, All Rights Reserved"
setup(
app=APP,
data_files=DATA_FILES,
options='py2app': OPTIONS,
setup_requires=['py2app'],
)
此外,还添加了图标定义和一些基本信息的 plist 条目。
最好使用如下所示的脚本触发整个构建:
#!/bin/sh
python3 -m venv venv
. venv/bin/activate
pip install PySide2
pip install py2app
python setup.py py2app
cp ./venv/lib/python3.8/site-packages/shiboken2/libshiboken2.abi3.5.15.dylib ./dist/app.app/Contents/Resources/lib/python3.8/lib-dynload/shiboken2
测试
这里是测试运行的屏幕截图:
【讨论】:
带有完整工作示例的详细答案,甚至还有演示。谢谢! 谢谢,这是第一组真正适用于为 pyside2 应用程序构建应用程序包的指令!你知道是否有任何理由需要这个“libshiboken2”东西但没有自动添加到包中? @RalfEbert 我没有任何进一步的信息,但我认为这可能只是一个错误。【参考方案6】:在尝试了很多 build a macOS bundle for a PySide2 application 的不同选项后,我发现以下步骤几乎可以立即使用。
此配方使用pyinstaller
创建 macOS 应用程序包,已在 macOS Catalina 10.15.7 上使用 Python 3.9.1、PySide2 5.15.2、pyinstaller 4.2 进行了测试。
安装 pyenv 和带有框架支持的最新 Python(请参阅 Pyenv、How to manage multiple Python versions and virtual environments 了解 pyenv 工作原理的一般介绍):
brew install pyenv
PYTHON_CONFIGURE_OPTS="--enable-framework" pyenv install 3.9.1
为示例创建一个文件夹,创建一个示例pyside应用程序:
mkdir hello && cd hello
nano hello.py
你好.py:
import sys
from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *
class MainWindow(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.setWindowTitle("Hello World")
self.button = QPushButton("Click me")
self.button.clicked.connect(self.say_hello)
self.setCentralWidget(self.button)
@Slot()
def say_hello(self, url):
self.button.setText("Hello!")
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
为项目创建一个venv,安装python包:
pyenv local 3.9.1
python3 -m venv venv
source venv/bin/activate
pip install pip pyside2 pyinstaller --upgrade
尝试使用 python 解释器运行应用程序:
python3 hello.py
创建一个 macOS 应用程序包:
pyinstaller --windowed hello.py
使用应用程序包运行应用程序:
open dist/hello.app
查看生成的hello.spec
进行构建配置,使用pyinstaller hello.spec
重新构建应用程序。
【讨论】:
以上是关于如何从具有 PySide2 GUI 的 python 脚本构建一个 mac os 应用程序?的主要内容,如果未能解决你的问题,请参考以下文章
Pyside2 QGuiApplication,Gui冻结按钮点击