ここには、PythonのMac独自のモジュールを使った例をいくつか書いておきます。
そのうち少しづつ増やしていこうと思います。
しかしながら、わたしが知っている程度の簡単なものしか書けません。ごめんなさい。
未整理のものは、わたしのPythonTipsのページにあります。
誤っているところや、おかしいところがあるかもしれません。お気づきの点がございましたら、わたしまでご連絡いただければ幸いです。
このページの目次
Pythonのファイルの命令(open)だけだと、パスを書かなければなりませんし、白紙アイコンのファイルしかできません。Macでお馴染みのファイルダイアログを使いたいものです。それには、macfsモジュールのStandardGetFile、StandardPutFileを使います。
MacPython2.3ではmacfs.StandardGetFileではなくEasyDialogs.AskFileForOpen、macfs.StandardGetFileではなくEasyDialogs.AskFileForSaveを使うそうです。
import macfs #ファイルを選択 fss, ok = macfs.PromptGetFile('ファイルを選んで!', 'TEXT') #PromptGetFileの初めの引数はプロンプト文、第2引数以降はオプション(なくてもよい)で #加えることのできるファイルタイプで、このタイプのファイルのみ表示します。 #macfs.PromptGetFile('ファイルを選んで!', 'TEXT', 'GIFf')のようにタイプを複数指定できます。 #第2引数を指定しなかった場合には全ファイルが表示されます。 #プロンプト文を使わない場合はStandardGetFileを使って、StandardGetFile('TEXT')とします。 #fssにはFsspecオブジェクトと呼ばれるものが代入されます。 #okには、ダイアログでCancelが押されずにファイルが選択されると1が代入されます。 if ok: #もし、Cancelボタンが押されずファイルが選ばれていたら path = fss.as_pathname() #Fsspecオブジェクトであるfssに対してas_pathnameメソッドを呼び出すと、 #fssのパスが返されます。それをpathに代入します。 #ここで通常通り(?)ファイルを開きます。 fp = open(path,'r') strings = fp.read() fp.close() print strings
蛇足:『PromptGetFileは2つの要素をもつタプルを返す』と考えて、以下のようにしてもいいのですが、Mac:Demoの例をみると、上のようにしていますね。
import macfs fss = macfs.PromptGetFile('ファイルを選んで!', 'TEXT', 'GIFf') if fss[1]: path = fss[0].as_pathname() fp = open(path,'r') strings = fp.read() fp.close() print strings
import macfs #ファイルのディレクトリと名前を選択 fss, ok = macfs.StandardPutFile('ディレクトリとファイル名を選んで!', '名称未設定') #StandardPutFileの初めの引数はプロンプト文、第2引数は保存するファイル名として #表示されます。 #okには、ダイアログでCancelが押されなかった場合に1が代入されます。 #fssにはFsspecオブジェクトが代入されます。 if ok: #もし、Cancelボタンが押されずファイルが指定されたら path = fss.as_pathname() #Fsspecオブジェクトであるfssに対してas_pathnameメソッドを呼び出すと、 #fssのパスが返されます。それをpathに代入します。 #ここで通常通り(?)ファイルを開きます。 fp = open(path,'w') fp.write('あいうえお') fp.close() #これで'名称未設定'ファイルに書き込めましたが、白紙のアイコンにしちゃうのは #Macユーザとして不満なので、ファイルのクリエータとタイプを設定しましょう。 fss.SetCreatorType('Pyth', 'TEXT') #これで'名称未設定'ファイルがPythonのテキストファイルのアイコンで表示されます。
MACFSモジュールにはmacfsで使う定数がおさめられています。
以下は、起動ディスクのデスクトップフォルダのパスを得ます。
import macfs, MACFS, os fsspec_disk, fsspec_desktop = macfs.FindFolder( MACFS.kOnSystemDisk, MACFS.kDesktopFolderType, 0) DesktopFolder_path = macfs.FSSpec((fsspec_disk, fsspec_desktop, '')).as_pathname() + os.curdir print DesktopFolder_path
これを実行すると、わたしの場合、
Performa HD:Desktop Folder:と表示されました。
同様にして、初期設定フォルダのパスを得るには、
import macfs, MACFS, os fsspec_disk, fsspec_preference = macfs.FindFolder( MACFS.kOnSystemDisk, MACFS.kPreferencesFolderType, 0) PreferencesFolder_path = macfs.FSSpec((fsspec_disk, fsspec_preference, '')).as_pathname() + os.curdir print PreferencesFolder_path
同様にして、ゴミ箱のパスを得ることができます。
fsspec_disk, fsspec_trash = macfs.FindFolder( MACFS.kOnSystemDisk, MACFS.kTrashFolderType, 0) trash_path = macfs.FSSpec((fsspec_disk, fsspec_trash, '')).as_pathname() + os.curdir
ゴミ箱へのパスを使って、ファイルをゴミ箱に入れることができます。
fss, ok = macfs.PromptGetFile('ゴミ箱へ入れるファイルを選んで!') if ok: filepath = fss.as_pathname() import findertools findertools.move(filepath, trash_path)
このページの最初の方にファイルのクリエータとタイプを
fss.SetCreatorType('Pyth', 'TEXT')
で設定しましたが、ファイルの拡張子(「.html」「.bin」など)に合わせてファイルのタイプ/クリエータを設定すると楽なこともあるかと思います。
ブラウザやFTPクライアントソフトには、「ダウンロードしたファイルのクリエータとタイプをInternet Config(インターネット設定機能拡張)での設定にする」機能があります。
それをやってみます。
Internet Configを扱うには、ic モジュールを使うらしいです。
icTest.py -------------------------- import ic import macfs icmap = ic.mapfile('.txt') fss = macfs.FSSpec('ReadMe') fss.SetCreatorType(icmap[2],icmap[1]) ----------------------------------
この「icTest.py」ファイルと同じフォルダ内に「ReadMe」というファイルがあると、「ReadMe」ファイルをInternet Configで設定されたクリエータ/タイプに設定します。アイコンが変わります。
私の場合、SimpleText のものになります。
ちょっと注釈を書くと...
icmap = ic.mapfile('.txt')
Internet Config の「拡張子等の対応」で'.txt'について設定されたものの情報をタプルで返すようです。
カッコ内はファイル名(文字列)か、Fsspecオブジェクト。
Python Documentationには「存在しないファイルの名前でもいい」みたいなことが書いてあるので(たぶん)、' . 拡張子' と考えてもいいのかもしれません。
ここで得た情報にあるクリエータとタイプを使います。
「拡張子等の対応」で設定されていない拡張子を '〜' に書くと、「icglue error : -666」が出ます。
fss = macfs.FSSpec('ReadMe')
クリエータとタイプを変える対象ファイルとして、実行している'icTest.py'と同じフォルダ内にある'ReadMe'のFsspecオブジェクトを得ています。何かファイルをコピーして'icTest.py'と同じフォルダ内に置き、「ReadMe」という名前に変更してください。
macfs.StandardGetFile() で得てもいいかもしれません。
fss.SetCreatorType(icmap[2],icmap[1])
ic.mapfile('.txt')が返すタプルのうち、3番目([2])がクリエータ、2番目([1])がタイプです。
それで、このように書いてみました。
私は、EasyFtpClientの中に icTest.py みたいなものを書き加えて、ダウンロードしたファイルのクリエータとタイプを設定して、アイコンが表示されるようにしています。
アプリケーションの場合、ボタンやメニューの操作などのGUIはもちろん大切ですが、簡単な音を出すこともインターフェイスとして大事だし、また、ただ単に楽しいものです。そんな簡単な音を出す方法を書いておきます。
以下はBeep音(警告音)を出します。
Test1.py -------------------------- import MacOS MacOS.SysBeep() ----------------------------------
うーーん。簡単です。「モニタ&サウンド」コントロールパネルで設定した警告音を出します。
もうひとつ。
Test2.py -------------------------- import Snd Snd.SysBeep(10000) ----------------------------------
Test1.pyと同じく警告音を出します。Snd.SysBeep()の()内の引数は duration(持続時間?)とありますが、小さな値にして長い警告音を鳴らしても、警告音の全部終わりまで鳴るので、詳しい意味は私にはわかりません。
次にテキストを話すものを。
Test3.py -------------------------- import macspeech macspeech.SpeakString("I am speech manager") ----------------------------------
「Speech」コントロールパネルで設定された音声で "I am speech manager" と話します。「Speech Manager」機能拡張がインストールされていないと動作しません。日本語を話すには、「Speech」コントロールパネルで「ひろし」「まさこ」を設定して、macspeech.SpeakString("わたしはスピーチマネージャーです") とすると例の棒読みで話します。
macspeech モジュールから音声の種類を設定したり、pitchやspeedも設定できるようです。
次はリソースの 'snd ' リソースのID 128 を再生します。
Test4.py -------------------------- import sys import Res import EasyDialogs sndID = 128 if sys.argv[0][-3:] == '.py': RSRC_NAME= sys.argv[0][:-3] + '.rsrc' else: RSRC_NAME= sys.argv[0] + '.rsrc' try: sndHandle = Res.GetResource('snd ', sndID) except Res.Error: try: print "open rsrc file" Res.FSpOpenResFile(RSRC_NAME, 1) sndHandle = Res.GetResource('snd ', sndID) except Res.Error: EasyDialogs.Message("Cannot open "+RSRC_NAME) sys.exit() """ここまでは、Test4.pyファイルを実行しているのなら 'Test4.rsrc'リソースファイルを開いて 実行し、すでにアプレットになっていた場合には 'snd 'リソースから読み出せ、 ということをやっています。""" ch = Snd.SndNewChannel(0,0,None) ch.SndPlay(sndHandle, 0) ----------------------------------
以下は 'snd 'リソースの作り方です。知らない人のために。
Test4.pyと同じフォルダ内に 'Test4.rsrc' リソースファイルを作ります。ResEditを開いて、Fileメニューから「New...」を選び、「Test4.rsrc」という名前でTest4.pyと同じフォルダ内にファイルを作ります。
Resourceメニューから「Create New Resource」を選ぶとたくさんのリソースタイプから選択するダイアログが出てくるので、'snd ' を選びます。
'snd ID = 128 from Test4.rsrc ' というウィンドウが作られますが、これを閉じます。
'snds from Test4.rsrc' ウィンドウが最前面に出て来ます。この中のID 128を選択して、Editメニューから「Cut」を選んで、消して下さい。
snd メニューから「Record New Sound...」を選ぶと録音/再生などのボタンのダイアログが表示されるので、録音ボタンを押し、「モニタ&サウンド」コントロールパネルで設定された経路から録音して下さい。私は「内蔵マイク」を選んでおいて、適当に叫びました。
「停止」ボタンを押し、再生してみたりして、これでいいなら「保存」ボタンを押します。
すると、ID 128 としてリソースができますので、保存してResEditを終了します。
上の Test4.py を実行すると、録音したID 128 が再生されます。
Snd.SndNewChannel、Snd.SndPlay の引数の詳しいことは私にはわかりません。
pydoc モジュールで __doc__ を読んでみるとか、Cのソースを読んでみたり、Inside Macintosh を読めばわかるのかも...私にはよくわかりませんでした。
Macintosh Library Modulesを訳していて、プログレスバーの使い方がわかりました。
bar1.py -------------------------------------------------- import EasyDialogs bar = EasyDialogs.ProgressBar("Test Bar",100,"Working...") for i in range(101): bar.inc() --------------------------------------------------
bar1.pyを実行すると、以下のようなウィンドウが表示されて、右端に達すると終了します。
バーが増えていくごとにラベルも変更してみます。
bar2.py -------------------------------------------------- import EasyDialogs bar = EasyDialogs.ProgressBar("Test Bar",100,"Working...") for i in range(101): bar.label("%s 回目 値:%d" % (i, bar.curval)) bar.inc() --------------------------------------------------
下が実行例です。
MacPython2.2以降では不定量プログレスインジケータが使えるようになりました。"不定量プログレスインジケータ"はぐるぐる回るバーです。普通の温度計型のバーは"定量プログレスインジケータ"というそうです。
bar3.py -------------------------------------------------- bar = EasyDialogs.ProgressBar("Test Bar",100,"Working...") for i in range(101): bar.label("%s 回目 値:%d" % (i, bar.curval)) bar.inc() bar.set(0,0) for i in range(101): bar.label("%s 回目 値:%d" % (i, bar.curval)) bar.inc() --------------------------------------------------
下が実行例です。最大値を0に設定しているせいか、値は0のままです。
トップページのAddQuote2Clip.pyのことを書いておきます。話題がなくなってきたので。。。(^ ^;
"""クリップボードのTEXTの行頭にquote文字を加える。 """ import string import EasyDialogs import Scrap import Res """MacPython2.1以降をお使いの場合は、上2行の代わりに from Carbon import Scrap from Carbon import Res を使ってください。""" #quote文字列の初期設定 QUOTE = '>' def addQuote(Singleline): """文字列Singlelineを受け取り、quoteStringを文字列の初めに 加えて返す関数""" return quoteString + Singleline #Handleを設定(Inside Macintosh:Toolbox Essential参照) handle = Res.Handle('') #クリップボードの内容のうち'TEXT'の”文字列の長さ”である[0]を取得 stuff = Scrap.GetScrap(handle,'TEXT')[0] if stuff > 0: #”文字列の長さ”が0より大きいとき(クリップボードにテキストがあるとき) #クリップボードの文字列を取得 stuff_data = handle.data if stuff_data != '': #いらないかもしれないけど、クリップボード文字列が''(空白)でなければ... #quoteとして使う文字列を尋ねる。 quoteString = EasyDialogs.AskString("Input Quote String", QUOTE) if quoteString != None: #quote文字列が入力されたら #クリップボード文字列を行で分けてリストにする lines = string.split(stuff_data,'\r') #各行の文字列(リストの各オブジェクト)にquote文字列を加える quoted_list = map(addQuote, lines) #各行の文字列(リストの各オブジェクト)に改行を加えて繋げる quoted_stuff = string.join(quoted_list, '\r') #クリップボードの内容を初期化 Scrap.ZeroScrap() #クリップボードに文字列を登録 Scrap.PutScrap('TEXT', quoted_stuff) #「加えたよ」のダイアログ EasyDialogs.Message("Added '%s' to Clipboard TEXT" % quoteString) else: #quote文字列が入力されてなかったら EasyDialogs.Message('Input Quote String !!') else: #クリップボード文字列が空白だったら EasyDialogs.Message('No TEXT in Clipboard!') else: #クリップボードに'TEXT'がなかったら EasyDialogs.Message('No TEXT Stuff in Clipboard!')