2011-10-19 12 views
14

में "पायथन" के अलावा अन्य सेट करना मैं पाइथन और क्यूटी का उपयोग कर एक जीयूआई एप्लीकेशन लिख रहा हूं। जब मैक पर अपना एप्लिकेशन लॉन्च करता हूं, तो स्क्रीन के शीर्ष पर मैक मेनू बार में पहला मेनू आइटम "पायथन" होता है। मैं अपने आवेदन का नाम होने के लिए आवेदन नाम पसंद करूंगा। मैं अपना प्रोग्राम नाम कैसे प्राप्त कर सकता हूं?मैक ओएसएक्स एप्लिकेशन मेनू मेनू बार आइटम को मेरे पायथन क्यूटी अनुप्रयोग

निम्नलिखित डेमो प्रोग्राम दो मेनू के साथ एक विंडो बनाता है: "पायथन", और "फू"। मुझे यह पसंद नहीं है, क्योंकि इससे मेरे उपयोगकर्ताओं को कोई फर्क नहीं पड़ता कि मैंने ऐप को पायथन या कोबोल में लिखा है या नहीं। इसके बजाय मुझे मेनू "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_()) 

मैक पर उस एप्लिकेशन मेनू नाम को मैं कैसे बदल सकता हूं? संपादित करें: यदि संभव हो तो मैं सिस्टम पायथन (या जो भी पाइथन उपयोगकर्ता पाथ पर है) का उपयोग जारी रखना पसंद करूंगा।

+0

आप अपना प्रोग्राम कैसे शुरू कर रहे हैं?मै मैक्स के बारे में बहुत कम जानता हूं, लेकिन ऐसा लगता है जैसे यह sys.argv [0] का मान डाल रहा है। – Falmarri

+0

मैं या तो "पायथन MyApp.py" या "./MyApp.py" टाइप करके प्रोग्राम शुरू करता हूं। दोनों मामलों में, sys.argv [0] "MyApp.py" या "./yAppApp.py" है। "पायथन" argv का हिस्सा नहीं है। –

+0

@ क्रिस्टफ़र ब्रंस: हम्म, आप सही हैं। मुझे नहीं पता कि मैंने क्यों सोचा था कि पाइथन के Argv ने अजगर को 'argv [0] 'के रूप में दिया है। मै मैक के बारे में कुछ भी नहीं जानता, हालांकि मैं विचारों से बाहर हूं। – Falmarri

उत्तर

8

आपको काम करने के लिए ओएसएक्स .app की आवश्यकता है, क्योंकि Info.plist फ़ाइल में वहां मौजूद एप्लिकेशन के लिए उपयोगकर्ता-दृश्य नाम शामिल है। यह पायथन पर डिफ़ॉल्ट है, जो प्रोग्राम मेनू के लिए आप शीर्षक देखते हैं। This blog पोस्ट आपके द्वारा उठाए जाने वाले चरणों की रूपरेखा तैयार करता है, जबकि OSX Developer Library में उस संपत्ति सूची पर दस्तावेज़ हैं जिन्हें आपको भरने की आवश्यकता है।

+0

यदि आवश्यक हो तो मैं एक ऐप बंडल बनाने के लिए तैयार हूं। लेकिन मैं उस ब्लॉग पोस्ट के निष्कर्ष "आप सिस्टम पायथन का उपयोग नहीं कर सकते" से बहुत नाखुश हूं। क्या सिस्टम पायथन का उपयोग करने का कोई तरीका नहीं है और "पायथन" मेनू आइटम नहीं है? –

+0

जाहिर है ... उद्धरण [एक अलग स्रोत] (http://arstechnica.com/open-source/guides/2009/03/how-to-deploying-pyqt-applications-on-windows-and-mac-os -x.ars/2): _ "यह बिल्कुल जरूरी है कि आप पाइथन-आधारित निर्भरताओं को बनाने से पहले पाइथन के सही संस्करण का उपयोग करने के लिए पर्यावरण को कॉन्फ़िगर करें।" _ कुछ समय पहले जिसे मैं असाइनमेंट से याद कर सकता हूं, इस तरह से निश्चित रूप से काम करता है, और एक बार हमारे पास तैनाती स्वचालित हो जाने के बाद, यह वास्तव में अब कोई मुद्दा नहीं था। मुझे इसके चारों ओर एक रास्ता नहीं पता, इसलिए ... मुझे लगता है कि कोई दूसरा रास्ता नहीं है, नहीं। – jro

+0

मुझे एक रास्ता मिला। मेरा जवाब देखें यदि आप सोचते हैं कि आप इसे एक पूर्ण समाधान में ले सकते हैं तो मैं आपको दूसरा जवाब देने के लिए प्रोत्साहित करता हूं। –

-3

मुझे लगता है कि आप ऐसा करने की जरूरत है:

win.setWindowTitle("MyApp") 

संपादित करें: यह PyQt के लिए है। मैं PySide में समकक्ष नहीं जानता।

+2

setWindowTitle() मेनू बार में नहीं, एप्लिकेशन टाइटल बार में टेक्स्ट रखता है। मुझे मैक मेनू बार में एप्लिकेशन मेनू आइटम को बदलने की जरूरत है। setWindowTitle() ऐसा नहीं करता है। –

5

मुझे इस प्रश्न का उत्तर कर्नेल मिला है। क्योंकि मैं खुद के अलावा किसी अन्य व्यक्ति को बक्षीस देना चाहता हूं (मैं ओपी हूं), कृपया, कोई भी, इस कर्नेल को ले लो और इसे अपने आप के एक पूर्ण उत्तर में विस्तारित करें।

मैं आवेदन मेनू के रूप में निम्नानुसार प्राप्त कर सकते हैं होने के लिए "MyApp":

ln -s /System/Library/Frameworks/Python.framework/Versions/2.6/Resources/Python.app/Contents/MacOS/Python MyApp 

./MyApp MyApp.py 

दो इस काम करने के लिए प्राप्त करने के लिए आवश्यक तत्व होते हैं:

  1. प्रतीकात्मक कड़ी नामित किया जाना चाहिए "MyApp "(या जो भी आप एप्लिकेशन मेनू में दिखाना चाहते हैं)
  2. प्रतीकात्मक लिंक सिस्टम पायथन ऐप बंडल के अंदर पाइथन निष्पादन योग्य को इंगित करना चाहिए। यदि आप/usr/bin/python से लिंक करते हैं, तो यह काम नहीं करता है, उदाहरण के लिए।

एक चतुर तरीका एक एप्लिकेशन बंडल या खोल स्क्रिप्ट है कि एक मजबूत तरीके से इस तंत्र का शोषण करने वाली बनाने के लिए होना चाहिए ...

+0

यदि मैं इसे सही ढंग से समझता हूं, तो आप बस निष्पादन योग्य का नाम बदल रहे हैं, इसलिए बोलने के लिए (मैं प्रतीकात्मक लिंक समझता हूं, लेकिन स्पष्ट होना)? हालांकि मैं अभी भी एक ऐप बंडल बनाने के पक्ष में हूं और वहां स्वचालन प्रयास डालता हूं, आप बस अपने एप्लिकेशन के लिए लॉन्चर बना सकते हैं जो पहले सिम्लिंक बनाता है, आपके ऐप को लॉन्च करता है और इसे बंद करने के बाद, लिंक हटा देता है। लेकिन जैसा कि कहा गया है, मैं एक उचित ऐप बंडल बनाने के पक्ष में अधिक हूं ... इसलिए कोई इसे स्वयं के जवाब में संकलित करने के लिए स्वतंत्र महसूस कर सकता है। – jro

+0

@jro मैं मानता हूं कि एक ऐप बंडल को सिम्लिंक रणनीति को सुंदर ढंग से लागू करने की आवश्यकता होगी। मैं एक ऐसे समाधान की तलाश में हूं जो दिखाता है कि ऐप बंडल में सिम्लिंक कैसे बनाएं और उपयोग करें। यदि कोई और विशिष्ट उत्तर दिखाई नहीं देता है, तो "ऐप बंडल का उपयोग करें" उत्तर सबसे अच्छा हो सकता है। –

1

एक बिल्डिंग क्रिस्टोफर 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) 
2

आप ऐप वितरित करने के लिए, तो symlinking अजगर द्विआधारी, काम की गारंटी नहीं है पर विचार है कि आम तौर विकास मशीनों पर प्रणाली अजगर डिफ़ॉल्ट अजगर नहीं है, और नियमित रूप से उन सबसे अधिक संभावना नहीं होगा चाहते हैं क्यूटी और PyQt स्थापित।

एक और विश्वसनीय दृष्टिकोण एक मूल ओएसएक्स बूटस्ट्रैपिंग बाइनरी है जो आपके पीईक्यूटी ऐप को शुरू करने का ख्याल रखेगा। py2app और PyInstaller दोनों देशी रैपर उत्पन्न कर सकते हैं। py2appaliased ऐप बनाने के लिए अच्छी तरह से काम किया, यानी एक रैपर जो आपके सिस्टम पर मौजूदा फाइलों के लिए सिम्लिंक करता है, इसे केवल आवश्यक पीईक्यूटी निर्भरताओं को बंडल करने के लिए प्राप्त करने के लिए गैर-तुच्छ साबित होता है। इसके अलावा py2app द्वारा py2app द्वारा उत्पन्न 'एलियाज्ड ऐप' काम करने से रोक देगा यदि आप इसे किसी अन्य फ़ोल्डर में ले जाते हैं क्योंकि सिम्लिंक उस फ़ोल्डर के सापेक्ष हैं जहां आप मूल रूप से बिल्ड स्क्रिप्ट चलाते हैं।

PyInstaller आउट-ऑफ-द-बॉक्स काम किया और मुझे एक ओएसएक्स बंडल मिला जिसमें सभी निर्भरता और पीईक्यूटी कोड लगभग 16 एमबी पर शामिल थे।

मैं एक स्टैंडअलोन OSX एप्लिकेशन के लिए अपने PyQt स्क्रिप्ट कन्वर्ट करने के लिए इस आदेश का प्रयोग किया है:

pyinstaller -w --noconfirm -i=myappicon.icns --clean -F myscript.py 

यह एक स्टैंडअलोन बंडल जो कुछ भी आप OSX शीर्षक पट्टी में अनुप्रयोग नाम के रूप में अपने .setWindowTitle() में प्रदर्शित करेगा कि उत्पन्न करता है।

एनबी: किसी कारण से, का संस्करण pip के माध्यम से स्थापित किया गया मेरे लिए काम नहीं किया। तो मैंने पीआईपी संस्करण हटा दिया, git version of pyinstaller क्लोन किया, python setup.py install किया और फिर यह एक आकर्षण की तरह काम किया।

फिर भी एक और एक ऐप्लिकेशन आवरण बनाने का विकल्प स्वचालक (स्पॉटलाइट में नाम टाइप करें), फ़ाइल के लिए जाना उपयोग करने के लिए है> नया> अनुप्रयोग> खोज के लिए और खींचें भागो खोल स्क्रिप्ट संपादक में और तहत शैल चयनbash, python। आप रन एप्पलस्क्रिप्ट और सेब स्क्रिप्ट का उपयोग करके अपने ऐप को बूटस्ट्रैप का उपयोग भी कर सकते हैं - उदाहरण के लिए, यदि आवश्यक विशेषाधिकारों के साथ चलाने के लिए उपयोगकर्ता के पासवर्ड से पूछने के लिए उपयोगी हो सकता है।

स्वचालक के लिए एक बेहतर विकल्प Platypus है - कि OSX क्षुधा में लिपियों के विभिन्न प्रकार लपेटता, और यह भी,, जीयूआई पाठ उत्पादन खिड़कियों की तरह कुछ अतिरिक्त सुविधाओं को प्रदान करता है व्यवस्थापक विशेषाधिकारों के साथ चल कस्टम चिह्न की स्थापना एक स्वतंत्र और खुला स्रोत अनुप्रयोग, आदि कोड github पर उपलब्ध है।

और आखिरकार, एक्सकोड में एक बेयरबोन ओएसएक्स ऐप बनाने का विकल्प है जो आपकी पीईक्यूटी स्क्रिप्ट लॉन्च करेगा (कुछ उदाहरण here), और अपने ऐप द्वारा आवश्यक अन्य कस्टम कार्यों को करें।

0

मुझे पता है कि यह वही नहीं है जो ओपी चाहता है, लेकिन यह पता चला कि यह इस मुद्दे के समाधान के लिए कुछ मूल्य जोड़ सकता है।

menubar.setNativeMenuBar(False) 

यह मेनूबार कारण होगा के रूप में यह उदा में दिखाई देता है प्रकट करने के लिए:

आप फ़ाइल मेनू आपके खिड़की यूआई के बजाय देशी मैक ओएस एक्स प्रणाली मेनूबार में देख सकते हैं विंडोज।

संबंधित मुद्दे