2.23 システムメニュー(menu、tkinter.Menu、tkinter.Menu.add_command、tkinter.Menu.add_cascade)
サブウィンドウのタイトルバーにあるシステムメニューに、メインウィンドウと同様にアプリケーション独自のメニュー項目を追加することができます。ただ、メインウィンドウと同様にシステムメニューは基本的に OS が設定するので、アプリケーションでの設定は OS の制限を受けます。1.23 システムメニューを参照して下さい。
次のプログラムは、メニューウィジェット「menu」を作成してサブウィンドウに登録しています。次いで、システムメニューに登録するための子のメニューオブジェクト「smenu」を作成して、「add_cascade」メソッドでメニューウィジェット「menu」に登録しています。子メニューオブジェクトに「add_command」メソッドでメニュー項目を設定して、関数を登録しています。関数はメニューテキストを「print」出力するようにしています。
ここで、プログラム 11 行目で、子メニューオブジェクトを作成するときに「tearoff」オプションに 0 を指定しています。このオプションは子メニューを切り離して表示することができるかの設定で、0 を指定することで切り離しを不可としています。詳細は 「メニューウィジェット」を参照して下さい。
import tkinter as tk | |
root = tk.Tk() | |
root.geometry('300x200+100+100') | |
sub = tk.Toplevel(root, width=300, height=200, bg='red') | |
sub.geometry('+140+120') | |
root.update() | |
root.wm_deiconify() | |
sub.wm_deiconify() | |
menu = tk.Menu(sub) | |
sub['menu']=menu | |
smenu = tk.Menu(menu, name='system', tearoff=0) | |
menu.add_cascade(menu=smenu) | |
def menufunc_1(): | |
print('menu_1') | |
def menufunc_2(): | |
print('menu_2') | |
smenu.add_command(label='menu_1', command=menufunc_1) | |
smenu.add_command(label='menu_2', command=menufunc_2) | |
root.mainloop() |
プログラムを実行すると、サブウィンドウのシステムメニューにメニュー項目が追加された下図のウィンドウが表示されます。
サブウィンドウでもメインウィンドウと同様に、アプリケーションで登録した子のシステムメニューに孫メニューを設定することができます。ただし、ウィンドウの表示順を設定する「wm_deiconify」メソッドの実行場所に注意する必要があります。メニューウィジェットを設定して「update」メソッドで描画を完了した後に実行する必要があります。
次のプログラムは、サブウィンドウにアプリケーションで登録した子のシステムメニューに孫メニューを設定しています。最初に、メニューウィジェット「menu」を作成してサブウィンドウに登録しています。次いで、システムメニューに登録するための子のメニューオブジェクト「smenu」を作成して、「add_cascade」メソッドでメニューウィジェット「menu」に登録しています。「smenu」は背景色としてピンク色を指定しています。
システムに登録した「smenu」に更に孫メニュー「menu_1」と「menu_2」を設定しています。孫メニュー「menu_1」に背景色として黄色を、「menu_2」に背景色として青色を設定しています。
孫メニューオブジェクトに「add_command」メソッドでメニュー項目を設定して、関数を登録しています。関数はメニューテキストを「print」出力するようにしています。
ここで、プログラム 8 行目で、子メニューオブジェクト「smenu」を作成するときに「tearoff」オプションは設定していません。デフォルトで切り離しが可能となっています。アプリケーションで登録したシステムメニューの孫メニューは OS の制限でメニューが切り離されないと有効になりません。 子メニューオブジェクト「smenu」に、メニュー「menu_1」と「menu_2」を「add_cascade」メソッドで孫メニューとして設定しています。
メニュを設定した後、20 行目で「update」メソッドを実行して 21、 22 行目でウィンドウを順に表示しています。
import tkinter as tk | |
root = tk.Tk() | |
root.geometry('300x200+100+100') | |
sub = tk.Toplevel(root, width=300, height=200, bg='red') | |
sub.geometry('+140+120') | |
menu = tk.Menu(sub) | |
sub['menu']=menu | |
smenu = tk.Menu(menu, name='system', bg='pink') | |
menu.add_cascade(menu=smenu) | |
menu_1 = tk.Menu(menu, bg='yellow') | |
menu_2 = tk.Menu(menu, bg='blue') | |
def menufunc_11(): | |
print('menu_11') | |
def menufunc_12(): | |
print('menu_12') | |
menu_1.add_command(label='menu_11', command=menufunc_11) | |
menu_1.add_command(label='menu_12', command=menufunc_12) | |
smenu.add_cascade(label='menu_1', menu=menu_1) | |
smenu.add_cascade(label='menu_2', menu=menu_2) | |
root.update() | |
root.wm_deiconify() | |
sub.wm_deiconify() | |
root.mainloop() |
プログラムを実行すると、サブウィンドウのシステムメニューにメニュー項目が追加された下図のウィンドウが表示されます。
追加したメニューの上に表示される(tear-off)のテキストをマウスで左クリックすると追加したメニューが分離して独立のウィンドウとして表示されます。このメニューの menu_1 のラベルをマウスので左クリックすると下図のように孫メニューが表示されます。
ここで、子および孫メニューの表示位置とサイズは設定していないので、システムが設定しています。メニューの設定の詳細は「メニューウィジェット」を参照して下さい。