第 2 章 サブウィンドウ

◀ 2.22 メニューバー   【目  次】  2.24 Windows 固有の属性 ▶

999999

 更新日:


 このホームページは Amazon Kindle 本の作成中の草稿です。日々、原稿を見直しているので、内容が変わることに留意して読んで下さい。本が出版され次第、このホームページは削除されます。

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 を指定することで切り離しを不可としています。詳細は 「メニューウィジェット」を参照して下さい。

1
import tkinter as tk
2
root = tk.Tk()
3
root.geometry('300x200+100+100')
4
sub = tk.Toplevel(root, width=300, height=200, bg='red')
5
sub.geometry('+140+120')
6
root.update()
7
root.wm_deiconify()
8
sub.wm_deiconify()
9
menu = tk.Menu(sub)
10
sub['menu']=menu
11
smenu = tk.Menu(menu, name='system', tearoff=0)
12
menu.add_cascade(menu=smenu)
13
def menufunc_1():
14
    print('menu_1')
15
def menufunc_2():
16
    print('menu_2')
17
smenu.add_command(label='menu_1', command=menufunc_1)
18
smenu.add_command(label='menu_2', command=menufunc_2)
19
root.mainloop()

 プログラムを実行すると、サブウィンドウのシステムメニューにメニュー項目が追加された下図のウィンドウが表示されます。

A002_SubWindow_02-23

 サブウィンドウでもメインウィンドウと同様に、アプリケーションで登録した子のシステムメニューに孫メニューを設定することができます。ただし、ウィンドウの表示順を設定する「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 行目でウィンドウを順に表示しています。

1
import tkinter as tk
2
root = tk.Tk()
3
root.geometry('300x200+100+100')
4
sub = tk.Toplevel(root, width=300, height=200, bg='red')
5
sub.geometry('+140+120')
6
menu = tk.Menu(sub)
7
sub['menu']=menu
8
smenu = tk.Menu(menu, name='system', bg='pink')
9
menu.add_cascade(menu=smenu)
10
menu_1 = tk.Menu(menu, bg='yellow')
11
menu_2 = tk.Menu(menu, bg='blue')
12
def menufunc_11():
13
    print('menu_11')
14
def menufunc_12():
15
    print('menu_12')
16
menu_1.add_command(label='menu_11', command=menufunc_11)
17
menu_1.add_command(label='menu_12', command=menufunc_12)
18
smenu.add_cascade(label='menu_1', menu=menu_1)
19
smenu.add_cascade(label='menu_2', menu=menu_2)
20
root.update()
21
root.wm_deiconify()
22
sub.wm_deiconify()
23
root.mainloop()

 プログラムを実行すると、サブウィンドウのシステムメニューにメニュー項目が追加された下図のウィンドウが表示されます。

A002_SubWindow_02-23

 追加したメニューの上に表示される(tear-off)のテキストをマウスで左クリックすると追加したメニューが分離して独立のウィンドウとして表示されます。このメニューの menu_1 のラベルをマウスので左クリックすると下図のように孫メニューが表示されます。
 ここで、子および孫メニューの表示位置とサイズは設定していないので、システムが設定しています。メニューの設定の詳細は「メニューウィジェット」を参照して下さい。

A002_SubWindow_02-23-2