एक बिल्डिंग क्रिस्टोफर Bruns जवाब, साथ ही script from "How to create Mac application bundle for Python script via Python" पर, यहाँ है पायथन स्क्रिप्ट जो उपयोगकर्ता पायथन स्क्रिप्ट के लिए एक बंडल (ऐप) बनाता है, जो मेनू में "पायथन" की बजाय ऐप नाम दिखाएगी। ऐसा करने के लिए, यह पाइथन के एक बंडल संस्करण का पता लगाने की कोशिश करता है, और ऐप के नाम से उसमें सिम्लिंक का प्रयास करता है। मैंने इसे एक wxpython स्क्रिप्ट के साथ परीक्षण किया, लेकिन यह क्यूटी के लिए भी काम करना चाहिए।
उपयोगकर्ता स्क्रिप्ट इसे ऐप में रखने के बजाय अपने मूल स्थान से चलाया जाता है। यदि आप अपनी स्क्रिप्ट को पुनर्वितरण के लिए एक बंडल (पायथन के साथ) में रखना चाहते हैं, तो इसके बजाय py2app देखें।
#!/usr/bin/env python
'''This creates an app to launch a python script. The app is
created in the directory where python is called. A version of Python
is created via a softlink, named to match the app, which means that
the name of the app rather than Python shows up as the name in the
menu bar, etc, but this requires locating an app version of Python
(expected name .../Resources/Python.app/Contents/MacOS/Python in
directory tree of calling python interpreter).
Run this script with one or two arguments:
<python script>
<project name>
The script path may be specified relative to the current path or given
an absolute path, but will be accessed via an absolute path. If the
project name is not specified, it will be taken from the root name of
the script.
'''
import sys, os, os.path, stat
def Usage():
print("\n\tUsage: python "+sys.argv[0]+" <python script> [<project name>]\n")
sys.exit()
version = "1.0.0"
bundleIdentifier = "org.test.test"
if not 2 <= len(sys.argv) <= 3:
Usage()
script = os.path.abspath(sys.argv[1])
if not os.path.exists(script):
print("\nFile "+script+" not found")
Usage()
if os.path.splitext(script)[1].lower() != '.py':
print("\nScript "+script+" does not have extension .py")
Usage()
if len(sys.argv) == 3:
project = sys.argv[2]
else:
project = os.path.splitext(os.path.split(script)[1])[0]
# find the python application; must be an OS X app
pythonpath,top = os.path.split(os.path.realpath(sys.executable))
while top:
if 'Resources' in pythonpath:
pass
elif os.path.exists(os.path.join(pythonpath,'Resources')):
break
pythonpath,top = os.path.split(pythonpath)
else:
print("\nSorry, failed to find a Resources directory associated with "+str(sys.executable))
sys.exit()
pythonapp = os.path.join(pythonpath,'Resources','Python.app','Contents','MacOS','Python')
if not os.path.exists(pythonapp):
print("\nSorry, failed to find a Python app in "+str(pythonapp))
sys.exit()
apppath = os.path.abspath(os.path.join('.',project+".app"))
newpython = os.path.join(apppath,"Contents","MacOS",project)
projectversion = project + " " + version
if os.path.exists(apppath):
print("\nSorry, an app named "+project+" exists in this location ("+str(apppath)+")")
sys.exit()
os.makedirs(os.path.join(apppath,"Contents","MacOS"))
f = open(os.path.join(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.sh</string>
<key>CFBundleGetInfoString</key>
<string>{:}</string>
<key>CFBundleIconFile</key>
<string>app.icns</string>
<key>CFBundleIdentifier</key>
<string>{:}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>{:}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>{:}</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>{:}</string>
<key>NSAppleScriptEnabled</key>
<string>YES</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
</dict>
</plist>
'''.format(projectversion, bundleIdentifier, project, projectversion, version)
)
f.close()
# not sure what this file does
f = open(os.path.join(apppath,'Contents','PkgInfo'), "w")
f.write("APPL????")
f.close()
# create a link to the python app, but named to match the project
os.symlink(pythonapp,newpython)
# create a script that launches python with the requested app
shell = os.path.join(apppath,"Contents","MacOS","main.sh")
# create a short shell script
f = open(shell, "w")
f.write('#!/bin/sh\nexec "'+newpython+'" "'+script+'"\n')
f.close()
os.chmod(shell, os.stat(shell).st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
आप अपना प्रोग्राम कैसे शुरू कर रहे हैं?मै मैक्स के बारे में बहुत कम जानता हूं, लेकिन ऐसा लगता है जैसे यह sys.argv [0] का मान डाल रहा है। – Falmarri
मैं या तो "पायथन MyApp.py" या "./MyApp.py" टाइप करके प्रोग्राम शुरू करता हूं। दोनों मामलों में, sys.argv [0] "MyApp.py" या "./yAppApp.py" है। "पायथन" argv का हिस्सा नहीं है। –
@ क्रिस्टफ़र ब्रंस: हम्म, आप सही हैं। मुझे नहीं पता कि मैंने क्यों सोचा था कि पाइथन के Argv ने अजगर को 'argv [0] 'के रूप में दिया है। मै मैक के बारे में कुछ भी नहीं जानता, हालांकि मैं विचारों से बाहर हूं। – Falmarri