在我的Python Qt应用程序中将Mac OSX应用菜单栏项设置为非“Python”
我正在用Python和Qt写一个图形界面应用程序。当我在Mac上启动我的应用时,屏幕顶部的菜单栏第一个菜单项是“Python”。我希望那里显示的是我的应用名称。请问我该怎么做才能把我的程序名称放上去呢?
下面这个示例程序创建了一个窗口,里面有两个菜单:“Python”和“Foo”。我不喜欢这样,因为对我的用户来说,知道我用Python还是COBOL写的应用并没有什么意义。我想要的菜单是“MyApp”和“Foo”。
#!/usr/bin/python
# This example demonstrates unwanted "Python"
# application menu name on Mac.
# Makes no difference whether we use PySide or PyQt4
from PySide.QtGui import *
# from PyQt4.QtGui import *
import sys
app = QApplication(sys.argv)
# Mac menubar application menu is always "Python".
# I want "DesiredAppTitle" instead.
# setApplicationName() does not affect Mac menu bar.
app.setApplicationName("DesiredAppTitle")
win = QMainWindow()
# need None parent for menubar on Mac to get custom menus at all
mbar = QMenuBar()
# Add a custom menu to menubar.
fooMenu = QMenu(mbar)
fooMenu.setTitle("Foo")
mbar.addAction(fooMenu.menuAction())
win.setMenuBar(mbar)
win.show()
sys.exit(app.exec_())
我该如何在Mac上更改这个应用菜单的名称呢?补充一下:如果可能的话,我希望继续使用系统自带的Python(或者用户路径下的任何Python)。
6 个回答
如果你打算分发这个应用程序,那么直接链接Python的可执行文件可能不太靠谱。因为通常在开发机器上,系统自带的Python并不是默认的Python版本,而且普通用户很可能没有安装Qt和PyQt。
一个更可靠的方法是创建一个本地的OSX启动程序,它可以帮助你启动你的PyQt应用。py2app和PyInstaller都可以生成本地的包装程序。虽然py2app在创建一个别名应用时表现良好,也就是一个链接到你系统上现有文件的包装程序,但要让它只打包所需的PyQt依赖项却不是一件简单的事。此外,使用py2app生成的带有--aliased
标志的“别名应用”如果移动到其他文件夹就会失效,因为这些链接是相对于你最初运行构建脚本的文件夹的。
PyInstaller
PyInstaller开箱即用,我最终得到了一个包含所有依赖项的OSX包,大小大约为16MB。
将Python脚本打包成独立的OSX应用:
pyinstaller -w --noconfirm -i=myappicon.icns --clean -F myscript.py
这会生成一个独立的包,应用名称会在OSX标题栏中显示你在.setWindowTitle()
中设置的内容。-w
这个选项很重要,因为它会创建一个带有正确.plist
文件的MacOS应用包。
注意:由于某种原因,通过pip
安装的pyinstaller
版本对我来说不太好用。所以我先卸载了原来的pip版本(pip uninstall pyinstaller
),然后安装了最新的develop
分支,命令如下:
pip install -v -e git+https://github.com/pyinstaller/pyinstaller.git@develop#egg=pyinstaller-github
之后它就顺利工作了。
Mac Automator
另一个创建应用包装程序的选项是使用Automator(在Spotlight中输入名字即可找到),然后选择文件 > 新建 > 应用程序,搜索并拖动运行Shell脚本到编辑器中,在Shell下选择bash
或python
。你也可以使用运行AppleScript,通过AppleScript启动你的应用——这在你需要用户输入密码以获得更高权限时会很有用。
比Automator更好的选择是Platypus——这是一个免费的开源应用,可以将各种类型的脚本打包成OSX应用,还提供一些额外功能,比如图形界面文本输出窗口、以管理员权限运行、设置自定义图标等。代码可以在github上找到。
你还可以选择在Xcode中创建一个简单的OSX应用来启动你的PyQt脚本(一些示例可以在这里找到),并执行你应用所需的其他自定义任务。
注意:请记住,调用你Python代码的应用包如果使用了预定义的解释器,那就是一个“浅层”的应用包,它将依赖于你本地安装的Python依赖项。很可能在其他人的Mac上无法直接使用。
Nuitka
你也可以尝试Nuitka(pip3 install nuitka
),这个项目旨在通过将你的Python代码转换为C++并编译,来构建真正的本地可执行文件。
使用nuitka
构建本地应用的示例:
nuitka3 --follow-imports --python-flag=no_site --verbose --standalone --show-progress --show-modules --output-dir=my_build_dir myscript.py
这将创建一个包含库的mac可执行文件,放在my_build_dir
文件夹中。你需要自己将它们包装成一个MacOS应用包,比如使用Platypus或Automator。
我找到了一些关于这个问题的答案的核心内容。因为我想把奖励给其他人(我是提问者),所以请大家把这个核心内容扩展成你们自己的完整答案。
我可以通过以下方式让应用菜单显示为"MyApp":
ln -s /System/Library/Frameworks/Python.framework/Versions/2.6/Resources/Python.app/Contents/MacOS/Python MyApp
./MyApp MyApp.py
要让这个工作,有两个要素:
- 符号链接的名字必须是"MyApp"(或者你想在应用菜单中显示的任何名字)
- 这个符号链接必须指向系统Python应用包里的Python可执行文件。如果你链接到/usr/bin/python,这样是行不通的。
一定有聪明的方法可以创建一个应用包或脚本,利用这个机制,让它更稳健……