我的 python 代码在控制台中运行良好。它加载给定的 Excel 文件并使用 openpyxl 将一些数据写入其中:
try:
# process given excel file
PLIK = sys.argv[1]
process_the_file(PLIK) # my function
except IndexError:
print('No file to process')
我想用在 Mac 系统上运行的脚本制作一个应用程序。我尝试像这样使用 pyinstaller:
>>> pyi-makespec my_script.py --onedir --windowed --argv-emulation --icon logo.icns --osx-bundle-identifier com.comp.my.script --name The_Script
创建 .spec 文件后,我在其中添加 Mac 所需的数据:
info_plist={
'NSPrincipalClass': 'NSApplication',
'NSAppleScriptEnabled': False,
'CFBundleDocumentTypes': [{
'CFBundleTypeName': "XLSX input table document",
'CFBundleTypeExtensions': [
'xlsx',
],
'CFBundleTypeRole': "Editor",
'LSItemContentTypes': [
'com.microsoft.excel.xls'
],
'LSHandlerRank': 'Owner'
}],
}
我运行命令来创建应用程序:
>>> pyinstaller The_Script.spec
现在我尝试将应用程序与 example.xslx 文件一起使用。我单击 example.xlsx 文件以使用 The_Script.app 打开它,但它不起作用 - 在调试中我看到消息“没有要处理的文件”。就像应用程序看不到我传递的参数一样。 我这样调试:
>>> open dist/The_Script.app/Contents/MacOS/The_Script --args example.xlsx
我想我阅读了所有文档和互联网,但我不知道出了什么问题。
环境:
macOS Sonoma 14.4
Python 3.9.6
pyinstaller 6.4.0
主要问题是
--argv_emulation
的作用非常有限。它允许您将文档直接拖到应用程序包上,然后打开该文档。但如果您的应用程序已经打开,即使这样也不起作用。正如您所观察到的,它不适用于从文档本身的上下文菜单打开您的应用程序。 在 pyinstaller 文档中阅读更多相关信息
更全面的解决方案需要拦截苹果事件。如果您可以使事件拦截起作用,请不要使用
--argv_emulation
。 详细信息取决于您制作应用程序的具体方式:
如果您使用
tkinter
作为 GUI 工具包,请使用 ::tk::mac::OpenDocument
命令注册您的回调。 (我个人没有使用过这个技术)
如果您使用 PySide/PyQt 作为 GUI 工具包,请拦截 QFileOpenEvent 并将其转发到您的回调。在 PySide6 中:
class MyApplication(QApplication):
def event(self, event):
# Intercept Mac file open events
if event.type() == QEvent.FileOpen:
self.on_file_open_event.emit(event.file())
return super().event(event)
on_file_open_event = QtCore.Signal(str)
app = MyApplication()
...
app.on_file_open_event.connect(my_load_file_slot)
...
sys.exit(app.exec())