2009-09-29 10 views

答えて

6

OS X 10.5以降、OS XにはPyObjCブリッジ、Python-Objective-Cブリッジが付属しています。 BridgeSupportフレームワークを使用してObjective-CフレームワークをPythonにマッピングします。 MacRubyとは異なり、PyObjCは古典的なブリッジです。Python側には各ObjCオブジェクトのプロキシオブジェクトがあり、逆もあります。 PyObjCでアプリケーション全体を書くことも可能です(XcodeにはPyObjCの基本的なサポートがあり、PythonのXcodeのアプリケーションとファイルテンプレートは上記リンクのPyObjC SVNからダウンロードできます)。多くの人々はユーティリティやアプリスクリプト/プラグインのためにそれを使用しています。 Appleの開発者サイトではPyObjC経由でCocoaアプリケーションを開発するためのintroductionもありますが、PyObjCは少し古くなっていますが、あなたには良い概観かもしれません。あなたのケースでは

、次のコードは[NSSpeechSynthesizer availableVoices]を呼び出します:私のSLマシン上

(
    "com.apple.speech.synthesis.voice.Agnes", 
    "com.apple.speech.synthesis.voice.Albert", 
    "com.apple.speech.synthesis.voice.Alex", 
    "com.apple.speech.synthesis.voice.BadNews", 
    "com.apple.speech.synthesis.voice.Bahh", 
    "com.apple.speech.synthesis.voice.Bells", 
    "com.apple.speech.synthesis.voice.Boing", 
    "com.apple.speech.synthesis.voice.Bruce", 
    "com.apple.speech.synthesis.voice.Bubbles", 
    "com.apple.speech.synthesis.voice.Cellos", 
    "com.apple.speech.synthesis.voice.Deranged", 
    "com.apple.speech.synthesis.voice.Fred", 
    "com.apple.speech.synthesis.voice.GoodNews", 
    "com.apple.speech.synthesis.voice.Hysterical", 
    "com.apple.speech.synthesis.voice.Junior", 
    "com.apple.speech.synthesis.voice.Kathy", 
    "com.apple.speech.synthesis.voice.Organ", 
    "com.apple.speech.synthesis.voice.Princess", 
    "com.apple.speech.synthesis.voice.Ralph", 
    "com.apple.speech.synthesis.voice.Trinoids", 
    "com.apple.speech.synthesis.voice.Vicki", 
    "com.apple.speech.synthesis.voice.Victoria", 
    "com.apple.speech.synthesis.voice.Whisper", 
    "com.apple.speech.synthesis.voice.Zarvox" 
) 

(ブリッジNSCFArray)を返し

from AppKit import NSSpeechSynthesizer 

NSSpeechSynthesizer.availableVoices() 

3

おそらくPyObjCが必要です。それは、私は実際に自分自身を使ったことはありません(私はデモを見たことがあります)ので、あなたが必要とすることができるかどうかは確信していません。

4

10.5以降のMac OS Xには、Pythonとあなたが望むことをさせるobjcモジュールが同梱されています。

例:

from Foundation import * 

thing = NSKeyedUnarchiver.unarchiveObjectWithFile_(some_plist_file) 

あなたはより多くのドキュメントhereを見つけることができます。

+0

+1。 –

+1

Foundationのみのobjcモジュールをインポートする必要はありません。 –

+0

ハァッ、そうです。私の例を更新します。 – Benno

19

他の人が触れたように、PyObjCは行く方法です。しかし、完全ために、ここであなたはそれがPyObjCがインストールされていない前10.5 OS Xのバージョンで動作する必要がある場合には、あなたがctypesでそれを行うことができます方法は次のとおりです。

import ctypes 
import ctypes.util 

# Need to do this to load the NSSpeechSynthesizer class, which is in AppKit.framework 
appkit = ctypes.cdll.LoadLibrary(ctypes.util.find_library('AppKit')) 
objc = ctypes.cdll.LoadLibrary(ctypes.util.find_library('objc')) 

objc.objc_getClass.restype = ctypes.c_void_p 
objc.sel_registerName.restype = ctypes.c_void_p 
objc.objc_msgSend.restype = ctypes.c_void_p 
objc.objc_msgSend.argtypes = [ctypes.c_void_p, ctypes.c_void_p] 

# Without this, it will still work, but it'll leak memory 
NSAutoreleasePool = objc.objc_getClass('NSAutoreleasePool') 
pool = objc.objc_msgSend(NSAutoreleasePool, objc.sel_registerName('alloc')) 
pool = objc.objc_msgSend(pool, objc.sel_registerName('init')) 

NSSpeechSynthesizer = objc.objc_getClass('NSSpeechSynthesizer') 
availableVoices = objc.objc_msgSend(NSSpeechSynthesizer, objc.sel_registerName('availableVoices')) 

count = objc.objc_msgSend(availableVoices, objc.sel_registerName('count')) 
voiceNames = [ 
    ctypes.string_at(
    objc.objc_msgSend(
     objc.objc_msgSend(availableVoices, objc.sel_registerName('objectAtIndex:'), i), 
     objc.sel_registerName('UTF8String'))) 
    for i in range(count)] 
print voiceNames 

objc.objc_msgSend(pool, objc.sel_registerName('release')) 

それはかなりではありませんしかし、それは仕事を完了します。利用可能な名前の最終的なリストは、上記変数voiceNamesに格納されています。

2012-4-28更新:すべてのパラメータと戻り値の型が32ビット整数ではなくポインタとして渡されるようにして、64ビットPythonビルドで動作するように修正されました。例えば、

+0

こんにちは、これは10.6でクラッシュします - それはなぜですか? –

+3

@Ecir:チップをありがとう、私は元のコードが最初に働いて驚いています。問題は、ポインタ(クラスポインタとインスタンスポインタ)のすべてがctypesの働きによって32ビットに切り詰められていたため、クラッシュが発生していました。これを修正するために、すべての結果タイプと引数タイプを明示的にポインタに設定するようにコードを変更しました。 –

+0

ありがとうございました。 –

関連する問題