2011-10-19 16 views
14

Python ve Qt kullanarak bir GUI uygulaması yazıyorum. Uygulamamı Mac'te başlattığımda, ekranın üst tarafındaki Mac menü çubuğundaki ilk menü öğesi "Python". Uygulama ismimin başvurumun adı olmasını tercih ederim. Program ismimi oraya nasıl alabilirim?Mac OSX Uygulama Menüsü menü çubuğu öğesini python Qt uygulamasında "Python" dışında bir değere ayarlama

Aşağıdaki demo programı iki menü içeren bir pencere oluşturur: "Python" ve "Foo". Bunu beğenmedim, çünkü kullanıcıları python veya COBOL'da yazıp yazmamam farketmez. Bunun yerine "MyApp" ve "Foo" menülerini istiyorum.

#!/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'te bu uygulama menüsü adını nasıl değiştirebilirim? DÜZENLEME: Mümkünse, sistem pythonunu (ya da python'un kullanıcı PATH'sında ne varsa) kullanmaya devam etmeyi tercih ederim.

+0

Programınızı nasıl başlatıyorsunuz?Mac'ler hakkında çok az şey biliyorum, ama sanki sys.argv [0] değerini buraya koymuş gibi geliyor. – Falmarri

+0

Programı "python MyApp.py" veya "./MyApp.py" yazarak başlatırım. Her iki durumda da, sys.argv [0] "MyApp.py" veya "./MyApp.py" dir. "Python" argv'nin bir parçası değildir. –

+0

@Christpher Bruns: Hmm, haklısın. Neden python'un argvininin pythonunu argv [0] 'olarak verdiği fikrini bilmiyorum. Yine de, Mac'lerle ilgili hiçbir şey bilmiyorum, bu yüzden hepimiz bir fikrim yok. – Falmarri

cevap

8

Burada çalışmak için bir OSX .app dosyasına ihtiyacınız var gibi görünüyor, orada bulunan uygulama için kullanıcı tarafından görülebilir adı içeren Info.plist dosya var. Bu, program menüsü için gördüğünüz başlık olan Python'a varsayılan değerdir. This blog post, yapmanız gereken adımları özetlerken, OSX Developer Library doldurmanız gereken özellik listesindeki belgelere sahip.

+0

Gerekirse bir Uygulama paketi oluşturmak istiyorum. Ama o blog yayınının "sistem pythonunu kullanamazsın" sonucundan oldukça memnunum. Sistem pythonunu kullanmanın ve "Python" menü maddesine sahip olmanın gerçekten bir yolu yok mu? –

+0

Görünüşe ... alıntı [farklı kaynak] (http://arstechnica.com/open-source/guides/2009/03/how-to-deploying-pyqt-applications-on-windows-and-mac-os -x.ars/2): _ "Python tabanlı bağımlılıkları oluşturmadan önce ortamı Python'un doğru sürümünü kullanacak şekilde yapılandırmanız kesinlikle zorunludur." _ Bir süre önce bir görevden hatırlayabildiğim kadarıyla, bu şekilde emin olmak için çalışıyor ve dağıtım otomatik hale getirildikten sonra, artık bir sorun değildi. Bunun bir yolunu bilmiyorum, yani ... sanırım başka yolu yok, hayır. – jro

+0

Bir yol buldum. Cevabımı gör. Daha eksiksiz bir çözümden yararlanabileceğinizi düşünüyorsanız, ikinci bir cevap vermeye başlamanızı öneririm. –

-3

bunu yapman gerek:

win.setWindowTitle("MyApp") 

Düzenleme: Bu PyQt'de içindir. PySide'de denkliği bilmiyorum.

+2

setWindowTitle(), metni menü çubuğunda değil, uygulama başlık çubuğuna yerleştirir. Mac menü çubuğundaki Uygulama Menüsü öğesini değiştirmem gerekiyor. setWindowTitle() bunu yapmaz. –

5

Bu sorunun yanıtının çekirdeğini buldum. Çünkü ben kendimden başka birisine (OP'im) lütuf vermek istiyorum, lütfen, herhangi birini, bu çekirdeği alıp, kendi başına daha eksiksiz bir cevaba dönüştürün.

şöyle ben "Uygulamam" olarak uygulama menüsünü alabilirsiniz: "BenimUygulamam sembolik bağlantı adlandırılmış olması gerekir

  1. :

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

    bu işe almak için gereken iki unsur vardır "(veya Uygulama Menüsünde görünmesini istediğiniz her şey)

  2. Sembolik bağlantı, sistem python uygulama paketindeki Python yürütülebilir dosyasına işaret etmelidir. Örneğin,/usr/bin/python'a bağlanırsanız çalışmaz.

... sağlam bir şekilde bu mekanizmayı kullanan bir uygulama grubunun veya kabuk komut dosyası oluşturmak için akıllı bir yolu olmalı

+0

Eğer doğru anlıyorsam, sadece yürütülebilir dosyanın adını değiştiriyorsunuz, yani konuşmak için (sembolik bağları anlıyorum, fakat açık olmak gerekirse)? Yine de bir Uygulama paketi oluşturma ve oradaki otomasyon çabalarını yerine getirme avantajına sahip olmakla birlikte, uygulamanız için öncelikle sembolik bağlantı oluşturarak, uygulamanızı başlatır ve kapattıktan sonra bağlantıyı kaldıran bir başlatıcı oluşturabilirsiniz. Ancak, söylendiği gibi, uygun bir Uygulama paketi oluşturmayı daha çok tercih ediyorum ... bu yüzden birileri bunu kendi başına yanıtlamakta özgür olabilir. – jro

+0

@jro Simet taktiğinin zarif bir şekilde uygulanabilmesi için bir uygulama paketinin muhtemelen gerekli olacağını kabul ediyorum. Bir uygulama paketindeki sembolik bağlantıyı nasıl oluşturacağınızı ve kullanacağınızı gösteren bir çözüm arıyorum. Daha spesifik bir cevap görünmüyorsa, "bir uygulama paketi kullan" cevabınız en iyisi olabilir. –

1

Yapı Christopher Bruns cevap yanı sıra script from "How to create Mac application bundle for Python script via Python" üzerine, burada bir Kullanıcılarda Python betiği için bir paket (uygulama) oluşturan Python betiği, menülerde "Python" yerine uygulama adını gösterecektir. Bunu yapmak için, Python'un paketlenmiş bir sürümünü bulmaya ve uygulamanın adıyla bağlantı kurmaya çalışır. Bir wxpython betiğiyle test ettim, ama Qt için de çalışmalı.

Kullanıcı komut dosyası, uygulamaya yerleştirmek yerine özgün konumundan çalıştırılır. Komut dosyalarınızı yeniden dağıtım için bir pakete (python ile birlikte) yerleştirmek isterseniz, bunun yerine py2app'a bakın.

#!/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

sonra piton ikili genellikle geliştirme makinelerde sistem piton varsayılan piton olmadığını göz önünde bulundurarak işin garanti edilmez ve düzenli kullanıcıları büyük olasılıkla olmaz sembolik bağlantılarını, uygulamayı dağıtmak istiyorsanız Qt ve PyQt yüklü.

Daha güvenilir bir yaklaşım PyQt uygulamanızı başlatmaya özen gösteren yerli bir OSX önyükleme ikili ürününe sahip olmaktır. Hem py2app ve PyInstaller, yerel sarmalayıcılar oluşturabilir. py2app, aliased uygulamasının yaratılması için iyi çalışmış olsa da, yani sisteminizde varolan dosyalara takılan bir sarıcı, yalnızca gerekli PyQt bağımlılıklarını demet haline getirmeyi sağlayan bir sarıcı önemsiz değildir. Ayrıca, py2app tarafından oluşturulan --aliased bayrağının oluşturduğu 'aliased uygulaması', başka bir klasöre taşınırsanız çalışmayı durdurur, çünkü symlinks, yapı betiğini çalıştırdığınız klasöre göre değişir.

PyInstaller Kutudan çıktı ve tüm bağımlılıkları ve PyQt kodunu içeren bir OSX paketi var.

Ben tek başına bir OSX uygulamasına benim PyQT komut dosyası dönüştürmek için bu komutu kullanılır:

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

Bu OSX başlık çubuğundaki uygulama adı olarak .setWindowTitle() ne varsa gösterecektir bağımsız bir paket oluşturur.

NB: Bazı nedenlerle, pip aracılığıyla yüklenen pyinstaller sürümü benim için çalışmadı. Bu yüzden, pip sürümünü kaldırdım, git version of pyinstaller klonladı, bir python setup.py install yaptım ve sonra bir cazibe gibi çalıştı. Bir uygulama sarmalayıcı oluşturmak için

Yine başka bir seçenek Automator'ı (Spotlight adını yazın), Dosya gidin kullanmaktır> Yeni> Uygulama> arama ve sürükle Çalıştır kabuk komut dosyası düzenleyicisine ve altında Shell seçmekbash, python. Ayrıca, Run Applescript'u kullanarak ve uygulamanızı elma komut dosyasını kullanarak önyükleme yapabilirsiniz. Örneğin, yükseltilmiş ayrıcalıklarla çalıştırmak için kullanıcının parolasını istemeniz gerektiğinde yararlı olabilir.

Automator'ın için daha iyi bir alternatif Platypus olduğunu - OSX uygulamalar içine komut çeşitli sarar ve aynı zamanda özel simgeler ayarı, yönetici haklarıyla çalışan, gui metin çıktısı pencere gibi bazı ekstra özellikler sağlayan ücretsiz ve açık kaynak uygulaması, Kod github'da kullanılabilir.

Ve son olarak, Pycode komutunu (bazı örnekler here) başlatan ve uygulamanızın gerektirdiği diğer özel görevleri yapacak Xcode'ta barebone OSX uygulaması oluşturma seçeneği vardır.

0

Bunun OP'nin tam olarak istediği şey olmadığını biliyorum, ancak bu soruna bir çözüm aramaya biraz değer katabileceğini düşündüm. o örn görüneceği şekilde görünmesini Bu menü çubuğu neden olur

menubar.setNativeMenuBar(False) 

:

dosya menüler pencere arayüzünde yerine yerli Mac OS X sistem menüsüne görünmesini sağlayabilirsiniz Pencereler.

İlgili konular