-->

How to create Mac application bundle for Python sc

2020-06-06 02:03发布

问题:

I want to create a simple Mac application bundle which calls a simple Python script. I want to do that in Python.

Is there an easy way?

I tried to use py2app but that fails somehow, e.g.:

from setuptools import setup
setup(app=["foo.py"], setup_requires=["py2app"])

gives:

---------------------------------------------------------------------------
SystemExit                                Traceback (most recent call last)
/Users/az/<ipython console> in <module>()

/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/distutils/core.pyc in setup(**attrs)
    138         ok = dist.parse_command_line()
    139     except DistutilsArgError, msg:
--> 140         raise SystemExit, gen_usage(dist.script_name) + "\nerror: %s" % msg
    141 
    142     if DEBUG:

SystemExit: usage: ipython [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...]
   or: ipython --help [cmd1 cmd2 ...]
   or: ipython --help-commands
   or: ipython cmd --help

error: no commands supplied
Type %exit or %quit to exit IPython (%Exit or %Quit do so unconditionally).

I also tried:

import py2app.build_app
py2app.build_app.py2app("foo.py")

which also doesn't work (TypeError: dist must be a Distribution instance) (I'm not really sure how to use py2app.build_app.py2app and also haven't really found much examples / documentation about it).

Maybe setuptools/py2app or so are anyway overkill for my use case. I just want to create a simple empty app bundle, copy a Python script into it and configure its Info.plist in such a way that it calls the Python script.

回答1:

This is exactly what I wanted and works just fine:

#!/usr/bin/python

import sys
assert len(sys.argv) > 1

apppath = sys.argv[1]

import os, os.path
assert os.path.splitext(apppath)[1] == ".app"

os.makedirs(apppath + "/Contents/MacOS")

version = "1.0.0"
bundleName = "Test"
bundleIdentifier = "org.test.test"

f = open(apppath + "/Contents/Info.plist", "w")
f.write("""<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleDevelopmentRegion</key>
    <string>English</string>
    <key>CFBundleExecutable</key>
    <string>main.py</string>
    <key>CFBundleGetInfoString</key>
    <string>%s</string>
    <key>CFBundleIconFile</key>
    <string>app.icns</string>
    <key>CFBundleIdentifier</key>
    <string>%s</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
    <string>%s</string>
    <key>CFBundlePackageType</key>
    <string>APPL</string>
    <key>CFBundleShortVersionString</key>
    <string>%s</string>
    <key>CFBundleSignature</key>
    <string>????</string>
    <key>CFBundleVersion</key>
    <string>%s</string>
    <key>NSAppleScriptEnabled</key>
    <string>YES</string>
    <key>NSMainNibFile</key>
    <string>MainMenu</string>
    <key>NSPrincipalClass</key>
    <string>NSApplication</string>
</dict>
</plist>
""" % (bundleName + " " + version, bundleIdentifier, bundleName, bundleName + " " + version, version))
f.close()

f = open(apppath + "/Contents/PkgInfo", "w")
f.write("APPL????")
f.close()

f = open(apppath + "/Contents/MacOS/main.py", "w")
f.write("""#!/usr/bin/python
print "Hi there"
""")
f.close()

import stat
oldmode = os.stat(apppath + "/Contents/MacOS/main.py").st_mode
os.chmod(apppath + "/Contents/MacOS/main.py", oldmode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)


回答2:

Check out PyInstaller.

You give it the path to your python script and it analyzes all of your package imports, extracting any binary files that are needed and placing them into an archive.

I've used it for a fairly complex python program, and it worked for me.



回答3:

cxFreeze is best solution available as it is simple and time-saving.

first, create your program or application using python and then make setup file for your application.

And then build the app using build command python setup.py build, according to your requirement you need to make some changes, to make mac bundle or mac app refer this