rumps というPythonのライブラリを使うと Macのメーニューバーアプリを簡単にPythonで作ることが出来ます。
rumps
rumpsはPythonで簡単にメニューバーアプリを作成出来るライブラリ。
基本的な使い方は適当な関数にclickedというデコレーターを
当てる事でMenuItemと言うクラスのオブジェクトを作成し、
それをAppというクラスのオブジェクトに登録してrunすると
該当のメニューを持ったメニューバーアプリが出来ます。
インストール
インストールはpipを使って
$ pip install rumps
で。
rumpsがインストールできたら、 rumpsのレポジトリ のexamplesにある物を取ってきて実行してみたりすると色々わかると思います。
Hello World
凄くシンプルなものであれば、 適当に
1 2 3 4 5 6 7 8 9 10 11 12 | |
こんなスクリプトを作ってみます。
icon.pngというファイルを別途用意して同じディレクトリに置いておきます。
(16 x 16 pxの適当な画像。画像を用意するのが面倒ならiconの引数部分を消してください。)
@rumps.clicked("Hello World")というデコレーターを使っていますが、
ここで指定しているHello Worldの部分がMenuItemの名前になります。
関数はMenuItem型の引数を一つ持った物を作ります。
この様にしていつかメニューを用意して、
App型のオブジェクトにmenuを与えます。
Appの最初の引数はアプリの名前で何でも良し。
titleはメニューバー上のアイコンの右側に表示される文字列。
iconが表示されるアイコン画像になります。
どちらもデフォルト値はNoneですが、
両方共指定されない場合は最初に指定したアプリの名前が表示されます。
menuには使いたいメニューの名前の入った配列を渡します。
これで
$ python rumps_test.py
とすれば(もしくは実行権限を付与して./rumps_test.py)

こんな感じ(一番左)の物がメニューバーに表示され
Hello Worldの所をクリックすれば

こんな感じのWindowが出てきます。
alert/notification
hello_worldの中で使ってるalertという関数はこの様にWindowに情報を表示させます。
同様にnotificationという関数もあって、
こちらは通知センターに送られポップアップが表示されます。
alertの場合にはOKボタンの他にCancelボタンを表示せることも出来、
どちらを押したかを得られる様になってるので、
何か、実行しますか?、みたいな質問をして結果を見て処理することも可能です。
メニュータイトル
メニューの項目に表示されるのはメニュー名ですが、 この部分は
1 2 3 | |
の様に、各メニューに上のようにmenuを使ってアクセス出来るので、
それぞれのtitleを変更することで表示名を変える事も出来ます。
各メニューにはtitle以外にもiconの値もあり、
これに画像を指定することでメニューの左側に画像を表示させる
(タイトルを省略すれば画像だけにする)ことも出来ます。
アプリタイトル、アイコン
同様にアプリ自体のタイトルも
1 2 | |
みたいにすれば実行中に動的に変更すること出来ます。
これを使うと、メニューバーに何らの情報を表示したり、 アイコンの色を変えて通知したりすることも出来ます。
ちょっと使ってて気づいたのが、 アイコンが表示されてる状態でアプリのタイトルを途中で変更すると、 幅の変更が行われないらしく、長いタイトルを指定すると右側が切れてしまいました。 この際、一度アイコンの方ももう一度指定してあげると上手く幅が調整されました。
なのでタイトルの変更を行う際にはアイコンを変更しなくても タイトルの後にアイコンを設定する必要があります。
日本語メニュー
メニューバー名やアプリ名等に直接日本語は使えませんでしたが、 この様にしてタイトルを日本語にすることは可能です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
こんな感じで。
勿論、alertなどにも日本語を使うことが出来ます。
トグルメニュー
メニューをクリックして状態をトグルしたいような場合には
sender.stateの値を変更します。
最初は0になってますが、これを1にするとメニューの左側にチェックマークが付きます。
1 2 3 | |
の様なメニューを作っておくと状態を0, 1でトグルすることが出来、

こんな感じでクリックするたびにチェックマークが付いたり消えたりします。
これを使ってapp.menu["Enable"]の値を見て他の場所で色々と
処理すればOK。
入力させる
何らかの入力をさせたい場合にはWindowを使って
1 2 3 4 5 | |
こんな感じのメニューを作ると、

こんな感じの入力画面が出て来て、入力したものを
上の場合だとresponse.textで取ってくることが出来ます。
dimensionsは入力窓の大きさなので適当な大きさにします。
メニューツリー
MenuItemは関数を割り当てなくても作ることが出来ます。 また、MenuItemは、これ自体もMenuのリストを持っていて、 ここにMenuItemを加える事でツリー上のメニューを作ることが出来ます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
こんな感じ。
まず、Helloというメニューは定義されていないので 何もしないただタイトルだけのメニューが出来ます。
このままだと、このメニューは表示されますが、 薄いグレー表示でクリックしても何も起こらないものになります。
このメニューに対して、MikeとJaneというMenuItemを与えています。
ここではaddという関数を使って加えています。
MenuItemはその場で、Mikeという名前のメニューで、
hello_mikeという関数をコールバックとして持ったものを作ったりして与えています。

こんな感じになります。
Timer
メニューバーに表示させる様なアプリは、大概が何らかの事を バックグラウンドで実行してる物が多いと思います。
そのようなバックグラウンド処理を登録するには
timerというデコレーターを使います。
1 2 3 | |
こんなのを書いておくと、
App.run()と同時に、timerの引数にある数字毎(秒)に実行されます。
(メニューの様に登録する必要はありません。)
勝手に始まってもらっては困る、と言う場合には,Timerというクラスの
オブジェクトを自分で作ってスタートさせる事もできます。
1 2 3 4 5 6 7 | |
こんな感じ。 実行インターバルは途中でも
1 2 3 4 | |
の様にintervalの値を変更することで変更できます。
この際、タイマーが動いたままだと値が変更できないので、 上の様に一度止める必要があります。
このTimerを使って一定時間ごとに何かチェックを行って、 チェックにかかったらnotificationを出したり、 メニューバーのアプリタイトルやアイコンを変更して お知らせしたり、みたいな事が一番有り得そうな使い道だと思います。
アプリを終了する
デフォルトでQuitというメニューが追加され、 これを押すとアプリを終了します。
このメニュー名はquit_buttonという引数を
Appの初期化時に与える事で変更が出来ます。
(デフォルト値はQuit。)
この値をNoneにすると、メニューから直接終了する手段がなくなります。
この場合は自分で終了させるメニューを作成するなりしないといけませんが、
終了させるには
1
| |
を終了させたい所で呼ぶとAppオブジェクトのrunが終了します。
Appを継承したクラスを作って使う
ここまでの例ではグローバル関数を作り、デコレーターで装飾して Appで使う、と言う形でしたが、
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | |
こんな感じ。 複雑な事をしようと思うとクラスを使ったほうが簡単に色々できたりすると思います。
アプリ化
py2app というライブラリを別途使うことで、 このPythonスクリプトを簡単にアプリ化することも出来ます。
py2appを入れる際、OS X10.11 El Capitanだとちょっと躓いたので、 それについては下記を参照。
インストールはpipで
$ pip install py2app
まずはpy2appletというコマンドを使ってセットアップファイルを作ります。
$ py2applet --make-setup rumps_test.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |
こんな感じのファイルが出来ます。
このファイルの中で、OPTIONSという項目を
1 2 3 4 5 6 7 | |
の様に変更します。
LSUIElementは、アプリのplistの中のこの値を1にすると、
アプリを立ち上げてもDockに表示されなくなる値です。
メニューバーアプリなのでDockに表示されないようにします。
resourcesはアプリの中に含む外部ファイルのリストで、
ここではメニューバーアイコンを入れています。
また、アプリのアイコンを作って、それをアプリのアイコンとして指定したい場合は
iconfileという値を
'iconfile': 'app.icns',
な感じでOPTIONSに加えて上げると作ったアプリのアイコンとして使われます。
取り敢えず、これらの変更を加えて、
$ python setup.py py2app
を実行するとdistとbuildというディレクトリができてると思いますが、 distの中にrumps_test.appというアプリが出来ています。
これをFinderで表示してダブルクリックで実行してみれば、
(もしくはopen -W ./dist/rumps_test.app
先ほどと同じようなメニューバーのアプリが立ち上がります。
El Capitanでpy2appが上手く動かない時
以前、Yosemiteでちょっと動かした時は何も問題なかったと思うんですが、
El Capitanになってから使おうと思ったら
python setup.py py2appコマンドがエラーを出して上手くコンパイルできませんでした。
ちょっとメモが無くなってどの様なエラーだったか覚えてませんが、
pyobjec-core関連のエラーが出て(これ自体は既に入っていた状態)、
以下のページに辿り着いて、
ronaldoussoren / pyobjc / 課題 / #81 - pyobjc-core 2.5.1 install failing on OSX 10.9.2 — Bitbucket: https://bitbucket.org/ronaldoussoren/pyobjc/issues/81/pyobjc-core-251-install-failing-on-osx
以下のコマンドを実行してpyobjc関連の物を一通り入れたら
動くようになりました。
$ pip install pyobjc-core pyobjc-framework-Accounts pyobjc-framework-AddressBook pyobjc-framework-AppleScriptKit pyobjc-framework-AppleScriptObjC pyobjc-framework-Automator pyobjc-framework-CFNetwork pyobjc-framework-CalendarStore pyobjc-framework-Cocoa pyobjc-framework-Collaboration pyobjc-framework-CoreData pyobjc-framework-CoreLocation pyobjc-framework-CoreText pyobjc-framework-CoreWLAN pyobjc-framework-DictionaryServices pyobjc-framework-DiskArbitration pyobjc-framework-EventKit pyobjc-framework-ExceptionHandling pyobjc-framework-FSEvents pyobjc-framework-InputMethodKit pyobjc-framework-InstallerPlugins pyobjc-framework-InstantMessage pyobjc-framework-LatentSemanticMapping pyobjc-framework-LaunchServices pyobjc-framework-OpenDirectory pyobjc-framework-PreferencePanes pyobjc-framework-PubSub pyobjc-framework-QTKit pyobjc-framework-Quartz pyobjc-framework-ScreenSaver pyobjc-framework-ScriptingBridge pyobjc-framework-SearchKit pyobjc-framework-ServiceManagement pyobjc-framework-Social pyobjc-framework-StoreKit pyobjc-framework-SyncServices pyobjc-framework-SystemConfiguration pyobjc-framework-WebKit