GUI

Python Tkinter Menus(3) プラットフォームメニュー

各プラットフォームには、Tkによって特別に扱われるメニューバーがいくつか存在する。

macOS

macOSのTkは、独自のデフォルトメニューバーを提供している。これには、実行中のプログラム(この場合はプログラミング言語のシェル、例えば「Wish」、「Python」など)にちなんだメニュー、ファイルメニュー、標準の編集、ウィンドウ、ヘルプメニューがあり、すべてに様々なメニュー項目が用意されている。

このメニューバーを自分のプログラムで上書きすることもできるが、思い通りの結果を得るためには、いくつかの特定の手順(場合によっては特定の順序)を踏む必要がある。

ウィンドウ (またはその親ウィンドウ、例えばルートウィンドウ) にメニューバーを指定しない場合、Tk が提供するデフォルトのメニューバーが使用されることになる。

アプリケーションメニュー

すべてのメニューバーは、システム全体のリンゴのアイコンメニューから始まる。その右側には、最前面のアプリケーションのためのメニューがある。これは常に実行中のバイナリにちなんだ名前になっている。メニューバーをウィンドウにアタッチしたとき、 そのウィンドウにまだ特別な名前の .apple メニュー (後述) がなければ、 Tk はデフォルトのアプリケーションメニューを提供する。これには、”About Tcl & Tk” という項目があり、その後に標準的なメニュー項目である環境設定、サービスサブメニュー、項目の表示/非表示、そして終了が続く。

もし独自の .apple メニューを提供する場合、メニューバーがウィンドウにアタッチされたとき、Tk は標準的なアイテム (preferences 以降) を追加したアイテムの末尾に追加する。

よって、以下を確認すること。

  1. 各ウィンドウまたはルートウィンドウにメニューバーを作成する。メニューバーはまだウィンドウに取り付けないこと。
  2. メニューバーに.appleという名前のメニューを追加する。これは、アプリケーションメニューとして使用される。
  3. メニューは自動的にアプリケーションバイナリと同じ名前になる。これを変更したい場合は、スクリプトを実行するために使用するバイナリの名前を変更(またはコピーを作成)すること。
  4. アプリケーションメニューの一番上に表示させたい項目、例えば「About アプリ名」の項目を追加し、その後にセパレータを追加する。
  5. 上記をすべてを行った後、ウィンドウのメニュー設定オプションを使って、メニューバーをウィンドウに取り付ける。
win = Toplevel(root)
menubar = Menu(win)
appmenu = Menu(menubar, name='apple')
menubar.add_cascade(menu=appmenu)
appmenu.add_command(label='このアプリについて')
appmenu.add_separator()
win['menu'] = menubar

環境設定メニューの取り扱い

アプリケーションメニューには必ず「環境設定」というメニューアイテムがある。このメニューアイテムは、アプリケーションに環境設定ダイアログがある場合には、それを開く。そうでない場合は、このメニュー項目は無効になっている。

環境設定ダイアログを開くには、 ::tk::mac::ShowPreferences という名前の Tcl プロシージャの定義が必要。このプロシージャは環境設定メニューアイテムが選択されたときに呼び出される。このプロシージャが定義されていない場合、メニューアイテムは無効になる。

def showMyPreferencesDialog():
    ....
	
root.createcommand('tk::mac::ShowPreferences', showMyPreferencesDialog)

ヘルプメニューの提供

アプリケーションメニューと同様に、メニューバーに追加するヘルプメニューも、macOSでは特別な扱いを受ける。アプリケーションメニューに特別な名前(.apple)が必要だったように、ヘルプメニューにも.helpという名前を付ける必要がある。また、ヘルプメニューは、メニューバーがウィンドウに取り付けられる前に追加する必要がある。

ヘルプメニューには、ヘルプを検索するためのmacOS標準の検索ボックスと、”アプリ名 Help “という名前のアイテムが含まれることになる。アプリケーションメニューの名前と同様に、これはプログラムの実行ファイルに由来するもので、変更できない。環境設定ダイアログの処理方法と同様に、このヘルプアイテムに対応するためには、 ::tk::mac::ShowHelp という名前のTclプロシージャを定義する必要がありる。このプロシージャが定義されていない場合、メニュー項目は無効化されない。その代わり、ヘルプ項目が選択されたときにエラーを発生させる。

また、ヘルプメニューに他の項目を追加できる。これらは、アプリケーションのヘルプ項目の後に表示される。

helpmenu = Menu(menubar, name='help')
menubar.add_cascade(menu=helpmenu, label='ヘルプ')
root.createcommand('tk::mac::ShowHelp', ...)

ウインドウメニューの提供

macOSでは、「ウィンドウ」メニューに、最小化、ズーム、すべてを前面に出す、などの項目がある。また、現在開いているウィンドウのリストも含まれる。そのリストの前に、他のアプリケーション固有の項目が提供されることもある。

.windowという名前のメニューを用意することで、この標準的なウィンドウメニューが追加される。Tk は、余分なコードを書くことなく、すべてのトップレベルウィンドウと同期して、自動的にそれを維持する。また、このメニューにアプリケーション固有のコマンドを追加することもできる。これらのコマンドは、ウィンドウのリストの前に表示される。

windowmenu = Menu(menubar, name='window')
menubar.add_cascade(menu=windowmenu, label='Window')

その他のメニューハンドラ

ある標準的なメニュー項目を扱うのに、Tcl コールバック手続き、例えば tk::mac::ShowPreferences や tk::mac::ShowHelp を定義する必要がある。

他にも定義可能なコールバックがいくつかある。例えば、Quit メニューアイテムをインターセプトし、終了する前に変更を保存するようユーザに促すことができる。以下は、その完全なリストを示す。

tk::mac::ShowPreferences環境設定メニューアイテムが選択されたときに呼び出される。
tk::mac::ShowHelpアプリケーションのメインオンラインヘルプを表示するために呼び出される。
tk::mac::QuitQuit メニューアイテムが選択されたときや、ユーザがシステムをシャットダウンしようとしたときなどに呼び出される。
tk::mac::OnHideアプリケーションが非表示になったときに呼び出される。
tk::mac::OnShowアプリケーションが隠された後、表示されるときに呼び出される。
tk::mac::OpenApplicationアプリケーションが最初に開かれたときに呼び出される。
tk::mac::ReopenApplication既に実行されているアプリケーションをユーザが「再オープン」する際に呼び出される (例: Dock でアプリケーションをクリックしたとき)
tk::mac::OpenDocumentFinder がアプリケーションに一つ以上のドキュメント(例えば、ドロップされたもの)を開くように要求したときに呼び出される。この手続きには、開くべきファイルのパス名のリストが渡される。
tk::mac::PrintDocumentOpenDocument と同様で、ドキュメントは開くのではなく、印刷される必要がある。

詳しくは、tk_mac コマンドリファレンスを参照してください。

Windows

Windowsでは、各ウィンドウの枠の左上に「システム」メニューがあり、アプリケーションの小さなアイコンが表示されている。これには、「閉じる」「最小化」などのアイテムがある。Tkでは、システムメニューを作成すると、標準の項目の下に新しい項目を追加することができる。

sysmenu = Menu(menubar, name='system')
menubar.add_cascade(menu=sysmenu)

X11

X11 では、ヘルプメニューを作成すると、Tk はそのメニューが常にメニューバーの最後のメニューになるよううにする。

menu_help = Menu(menubar, name='help')
menubar.add_cascade(menu=menu_help, label='Help')