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