このページでは、Tkinter の「メニュー」ウィジェットの作成方法・使い方・設定方法等について説明していきたいと思います。
メニューとは
まずは、今回解説する「メニュー」がどのようなウィジェットであるのかについて簡単に説明していきます。
メニューバーを構成するウィジェット
メニューウィジェットは、GUI アプリのメニューバーを構成するウィジェットになります。
皆さんも、メニューバーの存在する GUI アプリを利用されたことがあるのではないかと思います。このメニューバーに表示される項目からファイルを開いたり、ファイルを保存したり、何かを表示したり、何かの設定を行ったりすることが可能ですね!
Tkinter で開発する GUI アプリにおいても、メニューウィジェットを利用することで、このメニューバーの表示を行うことができるようになります。
ちなみに、Windows と Mac の場合とでメニューバーの表示される位置が異なるので注意してください。Windows の場合は、上の図のように GUI アプリのメインウィンドウの中にメニューバーが表示されることになります。それに対し、Mac の場合は、PC の画面の最上部にメニューバーが表示されることになります。
このように、Windows と Mac とではメニューバーの作りが大きく異なり、メニューウィジェットで実現できることにも違いがあります。具体的には Mac ではメニューバーの見た目の設定が反映されなかったり、メニューウィンドウの分離等が実行不可だったりします。ただ、基本的なメニューバーは Mac でもメニューウィジェットによって表示可能ですので、Mac 利用者の方も是非以降の解説を読み進めていただければと思います。
スポンサーリンク
メニューウィジェットはグループ
少し話が逸れましたが、もう少しメニューウィジェットについての説明を続けたいと思います。
このメニューウィジェットを使いこなす上でポイントになるのが、このメニューウィジェットは「複数の要素を含むグループ」であることをしっかりと理解しておく点になると思います。
皆さんの利用経験のある GUI アプリのメニューバーでも、下の図の青枠が示すように、メニューバーは複数のアイテムから構成されていたはずです。メニューウィジェットは、各項目そのものではなく、それらの項目を管理するグループのことになります。
また、これらの項目をクリックすると、プルダウンメニューとして新たなメニューのグループが表示されることになります。このグループもメニューウィジェットの1つとなります。
さらに、このグループの中には、何かしらのアクションを実行する項目が含まれます。この項目をクリックすれば、例えばファイルを開いたり、直前の操作が取り消しされたり、何かしらのアプリの設定が行われたりすることになります。以降では、クリックすることで何かしらのアクションが実行される項目を「メニューアイテム」と呼びます。
ですが、このようなメニューアイテムだけでなく、次の階層のグループを示すアイテムが含まれていることもあります。そして、この次の階層のグループもメニューウィジェットとなります。
つまり、メニューウィジェットとは、「メニューアイテム、及び、他のメニューウィジェットを要素とするグループ」と考えることができます。そして、メニューウィジェットに他のメニューウィジェットを追加することで、多階層のメニューバーを実現することができることになります。
ここまで説明してきたように、メニューウィジェットとはメニューアイテムと他のメニューウィジェットを要素とするグループのことです。メニューアイテム自体のことではないので注意してください。
また、メニューウィジェットの1つはアプリのメインメニューとして設定することが可能です。このメインメニューとして設定されたメニューウィジェットに含まれる要素が、アプリのメニューバーとして表示されることになります。そして、そのメニューバーのアイテムがクリックされた際に他のメニューグループが表示されるようにすることで、一般的な GUI のメニューバーを Tkinter で開発するアプリでも実現することができるようになります。
このメニューウィジェットは作成時には空のグループとなります。そこに、メニューアイテムや他のメニューウィジェットを追加していくことで、メニューバーを作成していくことになります。このあたりは、次の章で詳しく解説していきます。
ここからは、グループであることが分かりやすいよう、メニューウィジェットのことを必要に応じて「メニューグループ」と呼ばせていただきます。
メニューウィジェットの使い方
続いては、メニューウィジェットの使い方について解説していきたいと思います。
まずは、このメニューウィジェットを利用した簡単なアプリのスクリプト例を示したいと思います。ちょっと長いですが、基本的には同じようなことを何回も実施しているだけで、やっていることはシンプルです。
import tkinter
import tkinter.font
def file_open():
print('file_open')
def file_save():
print('file_save')
def change_font():
# 色メニューグループで選択された色に設定
label.config(foreground=color_v.get())
# フォントメニューグループで設定されたフォントに設定
if italic_v.get():
slant = tkinter.font.ITALIC
else:
slant = tkinter.font.ROMAN
if bold_v.get():
weight = tkinter.font.BOLD
else:
weight = tkinter.font.NORMAL
font = tkinter.font.Font(size=40, slant=slant, weight=weight)
label.config(font=font)
# メインウィンドウを作成
app = tkinter.Tk()
app.geometry('400x300')
# 色用のウィジェット変数を作成
color_v = tkinter.StringVar(value='red')
# 斜体設定用のウィジェット変数を作成
italic_v = tkinter.BooleanVar(value=False)
# 太字設定用のウィジェット変数を作成
bold_v = tkinter.BooleanVar(value=False)
# ラベルを作成して配置
label = tkinter.Label(
app,
text='Hello World',
)
label.pack()
# デフォルト設定で文字のフォントを設定
change_font()
"""メニューグループの作成"""
# メインメニューグループを作成
menu = tkinter.Menu(
app
)
# ファイルメニューグループを作成
file_menu = tkinter.Menu(
menu,
tearoff=False
)
# 編集メニューグループを作成
edit_menu = tkinter.Menu(
menu,
tearoff=False
)
# 色メニューグループを作成
color_menu = tkinter.Menu(
edit_menu,
tearoff=False
)
# フォントメニューグループを作成
font_menu = tkinter.Menu(
edit_menu,
tearoff=False
)
"""メインメニューグループのアプリへの登録"""
# アプリのメニューバーにメニューグループを設定
app.config(menu=menu)
"""メニューグループへの要素の追加"""
# メインメニューグループへの要素の追加
menu.add_cascade(label='ファイル', menu=file_menu)
menu.add_cascade(label='編集', menu=edit_menu)
# ファイルメニューグループへの要素の追加
file_menu.add_command(label='開く', command=file_open)
file_menu.add_command(label='保存', command=file_save)
# 編集メニューグループへの要素の追加
edit_menu.add_cascade(label='色', menu=color_menu)
edit_menu.add_separator()
edit_menu.add_cascade(label='フォント', menu=font_menu)
# 色メニューグループへの要素の追加
color_menu.add_radiobutton(label='赤', variable=color_v, value='red', command=change_font)
color_menu.add_radiobutton(label='緑', variable=color_v, value='green', command=change_font)
color_menu.add_radiobutton(label='青', variable=color_v, value='blue', command=change_font)
# フォントメニューグループへの要素の追加
font_menu.add_checkbutton(label='斜体', variable=italic_v, command=change_font)
font_menu.add_checkbutton(label='太字', variable=bold_v, command=change_font)
# メインループ
app.mainloop()
このスクリプトを実行すれば、次の図のようなアプリが起動します。
ここで注目していただきたいのがメニューバーです。メニューバーに ファイル
と 編集
のメニューが存在することが確認できると思います。また、ファイル
をクリックすれば、開く
と 保存
メニューが、編集
をクリックすれば 色
と フォント
メニューが表示されることも確認できると思います。色
と フォント
の間には区切り線が存在することも確認できると思います。さらに、色
メニューにマウスカーソルを合わせれば、赤
・緑
・青
のメニューが表示され、フォント
メニューにマウスカーソルを合わせれば、斜体
・太字
メニューが表示されることも確認できると思います。
このように、アプリのメニューバーは多階層な構成になっています。そして、これは、前述のようにメニューグループの要素としてメニューアイテムと他のメニューグループを追加することで実現しています。具体的には、下の図のように複数のメニューグループを用意し、それらを他のメニューグループの要素に追加することで実現しています。
さらに、編集
メニュー内の 色
メニューから色を選択すれば、アプリに表示されている Hello World
の文字列の色が変化することも確認できると思います。 同様に、編集
メニュー内の フォント
メニューから 斜体
や 太字
をクリックすれば、アプリに表示されている Hello World
の文字列の形状が変化することも確認できるはずです。
メニューバーを実現する上では、単にメニューを多階層な構成にするだけでなく、上記のように、クリックされたメニューアイテムに応じて何らかの処理が実行されるようにする必要もあります。上記では、アプリ上に表示されている文字列の色やフォントの変更を行っていますが、他にもファイルを開いたり、何らかのデータを保存したり、新たなウィンドウを表示したりするような処理がクリックされたメニューアイテムに応じて実行されるようにアプリを開発する必要があります。
ということで、メニューバーを実現する上では、「メニューグループ(メニューウィジェット)の作成」や「メニューグループへのメニューアイテムや他のメニューグループの追加」、さらには「メニューアイテムクリック時の処理の実行」のあたりがポイントになると思います。
特に、このあたりに注目しながら、ここからメニューウィジェットの使い方についての詳細を解説していきます。
メニューウィジェット(メニューグループ)の作成
まず、メニューウィジェットを使うためにはメニューウィジェットの作成が必要となります。
Menu
クラスのコンストラクタ
メニューウィジェットは、tkinter の Menu
クラスのコンストラクタを実行することで作成することができます。
# app はメインウィンドウ等の親ウィジェット
menu = tkinter.Menu(
app
)
ここまで説明してきた通り、メニューウィジェットとはメニューグループのことになります。作成した時点ではメニューグループは空となっていますので、このメニューグループにメニューアイテムや他のメニューグループを追加する処理が必要となります。
また、その “他のメニューグループ” もメニューウィジェットとなりますので、メニューウィジェットは1つだけでなく、必要な分だけメニューウィジェットを作成する必要があることになります。前述で紹介したスクリプトにおいては、メニューウィジェットは下記の5つを作成しています。
menu
file_menu
edit_menu
color_menu
font_menu
Menu
クラスのコンストラクタの引数
Menu
クラスのコンストラクタの第1引数には、そのメニューグループが所属するウィジェットを指定します。例えば edit_menu
に color_menu
を追加するのであれば、color_menu
は edit_menu
に所属することになるため、color_menu
は下記のように作成する必要があります。
color_menu = tkinter.Menu(
edit_menu
)
また、前述のスクリプトにおいては、Menu
クラスのコンストラクタに引数 tearoff=False
を指定するようにしています。この tearoff
は、「分離実行アイテム」をメニューグループに追加するかどうかを指定する引数となります。
詳細は後述の tearoff の節で説明しますが、 メニューグループの「分離実行アイテム」をクリックすることで、そのメニューグループをアプリのウィンドウとは別のウィンドウに分離して表示することができます。
この項目を表示するかどうかを指定するのが tearoff
で、デフォルトは True
となっています。ただ、こういったメニューグループの分離は通常のアプリでは不要な機能なので、tearoff=False
を指定して分離実行アイテムを非表示にしています。
ちなみに、Mac の場合は tearoff
の指定に関わらず分離実行アイテムは非表示になり、メニューグループの分離は不可となります。
スポンサーリンク
メインメニューの登録
メニューグループが必要な分だけ作成できれば、次はメインメニューグループの設定を行います。メインメニューグループとは、下の図の青枠部分のような、アプリに直接表示されるメニューバーに該当するメニューグループとなります。
このメインメニューグループの設定は、下記のように引数に menu=メインメニューグループ
を指定して config
メソッドをアプリに実行させることで実施できます。
アプリ.config(menu=メインメニューグループ)
例えば、アプリが app
で menu
をメインメニューグループに設定したいのであれば、下記を実行すれば良いことになります。
app.config(menu=menu)
これにより、menu
がメインメニューグループに設定され、アプリのメニューバーとして表示されるようになります。
後は、そのメインメニューグループにメニューアイテムや他のメニューグループ等の要素を追加して、あなたが望むメニューバーを実現していけばよいだけになります。
メニューグループへの要素の追加
ということで、次はメニューグループへの要素の追加について解説していきます。ここまで、メニューグループへ追加可能な要素としては、メニューグループ・メニューアイテムの2種類を用いて説明してきましたが、より詳細にはメニューグループには下記の5つの要素を追加することが可能です。
- メニューグループ
- コマンドメニューアイテム
- チェックボタンメニューアイテム
- ラジオボタンメニューアイテム
- セパレーター
そして、この要素の追加はメニューグループにメソッドを実行させることで実施することができます。このメソッドは追加する要素の種類ごとに用意されており、各要素を追加するメソッドは下記のようになります。以降の解説では、これらを総称して呼ぶ場合には add_xxxxx
メソッドと呼ばせていただきます。
add_cascade
:メニューグループの追加add_command
:コマンドメニューアイテムの追加add_checkbutton
:チェックボタンメニューアイテムの追加add_radiobutton
:ラジオボタンメニューアイテムの追加add_separator
:セパレーターの追加
ここからは、これら5つの要素の追加の仕方や各種メソッドの使い方について解説していきます。
メニューグループの追加
メニューグループへの他のメニューグループの追加は add_cascade
メソッドで実施することができます。
add_cascade
メソッド
add_cascade
メソッドは、引数 label
に アイテム名
を指定し、さらに引数 menu
に 追加したいメニューグループ
を指定して実行します。
メニューグループ.add_cascade(
label='アイテム名',
menu=追加したいメニューグループ
)
これにより、メソッドを実行したメニューグループに対して、引数で指定した アイテム名
のアイテムが追加され、さらに、そのアイテムをクリックしたりマウスカーソルを合わせたりしたときに、引数で指定した 追加したいメニューグループ
が表示されるようになります。
add_cascade
メソッドの実行例
前述で示したスクリプトにおいては、下記のようにメインメニューグループとなる menu
に2回 add_cascade
メソッドを実行させています。
menu.add_cascade(label='ファイル', menu=file_menu)
menu.add_cascade(label='編集', menu=edit_menu)
そのため、メニューバーには ファイル
と 編集
が表示されるようになり、さらに、ファイル
にマウスカーソルを合わせれば file_menu
が、編集
にマウスカーソルを合わせれば edit_menu
が表示されることになります。
また、edit_menu
に対しても下記のように 2回 add_cascade
メソッドを実行させています(add_separator
については後述で解説します)。
edit_menu.add_cascade(label='色', menu=color_menu)
edit_menu.add_separator()
edit_menu.add_cascade(label='フォント', menu=font_menu)
そのため、編集
のクリックによって表示されるメニューには 色
と フォント
が追加され、さらに 色
にマウスカーソルを合わせれば color_menu
が、フォント
にマウスカーソルを合わせれば font_menu
が表示されることになります。
このように、メインメニューグループに add_cascade
メソッドでメニューグループを追加し、さらにそれらのメニューグループに add_cascade
メソッドで他のメニューグループを追加していくことで、多階層のメニューバーが実現できることになります。
スポンサーリンク
コマンドメニューアイテムの追加
メニューグループへのコマンドメニューアイテムの追加は add_command
メソッドで実施することができます。
コマンドメニューアイテムとは、クリック時に何らかの処理が実行されるメニューアイテムとなります。
add_command
add_command
は、引数 label
に アイテム名
を指定し、さらに引数 command
に クリック時に実行する関数
(or メソッド)を指定して実行します。
メニューグループ.add_command(
label='アイテム名',
command=クリック時に実行する関数
)
command
引数で クリック時に実行する関数
を指定するという点は、下記ページで解説しているボタンウィジェットと同様になります。なので、見た目はボタンとは異なりますが、イメージとしては add_command
はボタンウィジェットをメニューグループに追加するメソッドとなります。
add_command
の実行例
前述で示したスクリプトにおいては、下記のように file_menu
に2回 add_command
メソッドを実行させています。
file_menu.add_command(label='開く', command=file_open)
file_menu.add_command(label='保存', command=file_save)
そのため、file_menu
のグループには 開く
と 保存
のアイテムが追加され、さらに、開く
をクリックすれば file_open
が、保存
をクリックすれば file_save
が実行されることになります。
前述のスクリプトでは、これらの関数は単に print
を実行しているだけになりますが、例えば下記のページで紹介しているファイル選択ダイアログを表示するようにすれば、これらがクリックされた時にファイルを選択することができるようになり、選択されたファイルを開いたり、選択されたファイルに何らかの情報を保存したりするようなことも可能になります。
もちろん、command
に指定する関数の作り方によって、他にもさまざまな処理を実行するメニューアイテムが実現可能となります。
チェックボタンメニューアイテムの追加
メニューグループへのチェックボタンメニューアイテムの追加は add_checkbutton
メソッドで実施することができます。
チェックボタンメニューアイテムとは、何らかの設定の ON / OFF を切り替えるメニューアイテムとなります。”チェックボタン” が名前に付いていることからも分かるように、このチェックボタンメニューアイテムは下記ページで解説しているチェックボタンウィジェットのメニューアイテムバージョンとなります。
Tkinterの使い方:チェックボタン(Checkbutton)の使い方使い方もチェックボタンウィジェットと同様で、チェックボタンメニューアイテムはクリックするたびに、そのメニューの左側に表示されるチェックマークの ON / OFF が切り替わるようになっています。そして、そのメニューアイテムの ON / OFF に応じてアプリの動作を変化させることで、ユーザーがアプリの設定や機能等をメニューから ON / OFF できるようになります。
add_checkbutton
add_checkbutton
は、引数 label
に アイテム名
を指定して実行する必要があります。また、チェックボタンの ON / OFF の状態を判別するためには、引数 variable
に ON/OFF判別用のウィジェット変数
を指定する必要があります。さらに、チェックボタンメニューアイテムがクリックされた時に何らかの関数が実行されるようにしたいのであれば、引数 command
に クリック時に実行する関数
を指定する必要があります。
メニューグループ.add_checkbutton(
label='アイテム名',
variable=ON/OFF判別用のウィジェット変数,
command=クリック時に実行する関数
)
この「引数 variable
にウィジェット変数を指定して後からチェックの ON / OFF を判別できるようにする」という点に関しても先ほど紹介したチェックボックスと同様になります。チェックが ON / OFF の時にウィジェット変数にセットされる値を True
/ False
から変更したいのであれば、add_checkbutton
に引数 onvalue
と offvalue
を指定してやれば良いです。このあたりもチェックボックスと同様になります。
また、ここで使用しているウィジェット変数に関しては下記ページで解説していますので、詳細を知りたい方は下記ページを参照してください。
Tkinterの使い方:ウィジェット変数について解説【StringVar・BooleanVar・IntVar・DoubleVar】add_checkbutton
の実行例
前述で示したスクリプトにおいては、下記のように font_menu
に2回 add_checkbutton
メソッドを実行させています。
font_menu.add_checkbutton(label='斜体', variable=italic_v, command=change_font)
font_menu.add_checkbutton(label='太字', variable=bold_v, command=change_font)
そのため、font_menu
のグループには 斜体
と 太字
のアイテムが追加され、斜体
をクリックすれば italic_v
にセットされる値が True
/ False
で切り替わることになります。また、その値に応じて、斜体
のアイテムの左に表示されるチェックマークが表示されたり消えたりすることになります。同様に、太字
をクリックすれば bold_v
にセットされる値が True
/ False
で切り替わることになりますし、その値に応じて、太字
のアイテムの左に表示されるチェックマークが表示されたり消えたりすることになります。
さらに、これらの 斜体
や 太字
のアイテムがクリックされた際には change_font
が実行されるようになっており、この change_font
の中で italic_v
にセットされている値とbold_v
にセットされている値を取得し、Hello World
を表示しているラベルウィジェットに対して、それぞれの値に応じたフォントを設定するようにしています。そのため、これらがクリックされたタイミングで、Hello World
の文字列のフォントが変化することになります。
このように、add_checkbutton
や次に説明する add_radiobutton
で追加したメニューアイテムに関しては、単にメニューグループに追加するだけでなく、それらのメニューアイテムにセットされている値を後から取得し、それをアプリの動作や見た目・設定に反映するような処理も必要となります。そのため、それが実現できるようにメニューアイテムの追加時に実行するメソッドに適切な引数を指定する必要があり、このあたりがメニューウィジェットを使いこなす上での1つのポイントになると思います。
また、このページで紹介している例においては add_checkbutton
に command
引数を指定していますが、これはメニューアイテムクリック時に処理を実行したいからであって、別に command
引数が必須というわけではないので注意してください。例えばボタンウィジェットを別途用意し、それがクリックされた時にチェックメニューアイテムのチェックの ON / OFF を取得し、それをアプリの設定や動作に反映するのでも良いです。
ラジオボタンメニューアイテムの追加
メニューグループへのラジオボタンメニューアイテムの追加は add_radiobutton
メソッドで実施することができます。
ラジオボタンメニューアイテムとは、複数のラジオボタンメニューアイテムの中から1つのみを選択可能とするためのメニューアイテムとなります。”ラジオボタン” が名前に付いていることからも分かるように、このラジオボタンメニューアイテムは下記ページで解説しているラジオボタンウィジェットのメニューアイテムバージョンとなります。
Tkinterの使い方:ラジオボタン(Radiobutton)の使い方使い方もラジオボタンウィジェットと同様で、ラジオボタンメニューアイテムは複数のラジオボタンメニューアイテムでグループ化され、そのうちの1つが選択されると他のものが選択解除されるようになっています。そして、その選択されているメニューアイテムに応じてアプリの動作を変化させることで、ユーザーがアプリの設定や機能等をメニューから選択できるようになります。
add_radiobutton
の実行例
add_radiobutton
は、引数 label
に アイテム名
を指定して実行する必要があります。また、複数のラジオボタンメニューアイテムをグループ化する&選択中のラジオボタンメニューを判別するために引数 variable
に 選択中のアイテム判別用のウィジェット変数
を指定する必要があります。さらに、引数 value
には、そのラジオボタンメニューアイテムが選択されているときに ウィジェット変数に設定する値
を指定します。ラジオボタンメニューアイテムがクリックされた時に何らかの関数が実行されるようにしたいのであれば、引数 command
に クリック時に実行する関数
を指定する必要があります。
メニューグループ.add_radiobutton(
label='アイテム名',
variable=選択中のアイテム判別用のウィジェット変数,
value=ウィジェット変数に設定する値,
command=クリック時に実行する関数
)
前述の通り、ラジオボタンメニューアイテムは、同一のグループ内のアイテムのうち1つのみが選択可能となります。複数のアイテムのうち、1つのみを選択可能としたいのであれば、それらのアイテムに対応するラジオボタンメニューアイテムは同じグループとする必要があります。そして、ラジオボタンメニューアイテムは、variable
が同じウィジェット変数であるものが同じグループとして扱われるようになるため、グループ化したいラジオボタンメニューアイテムの variable
には、同じウィジェット変数を指定する必要があります。
また、そのウィジェット変数には、選択中のラジオボタンメニューアイテムの value
に指定された値がセットされることになります。したがって、そのウィジェット変数にセットされている値を取得すれば、どのラジオボタンメニューアイテムが選択中であるかを判別することができるようになります。ただし、同じグループのラジオボタンメニューアイテムの value
が重複すると判別できなくなるため、同じグループのラジオボタンメニューアイテムには異なる value
を指定する必要があります。
add_radiobutton
の実行例
前述で示したスクリプトにおいては、下記のように color_menu
に3回 add_radiobutton
メソッドを実行させています。
color_menu.add_radiobutton(label='赤', variable=color_v, value='red', command=change_font)
color_menu.add_radiobutton(label='緑', variable=color_v, value='green', command=change_font)
color_menu.add_radiobutton(label='青', variable=color_v, value='blue', command=change_font)
そのため、color_menu
のグループには 赤
と 緑
と 青
のアイテムが追加され、これらは同じグループのラジオボタンメニューアイテムとして扱われることになります。そして、赤
をクリックして選択すれば color_v
にセットされる値が 'red'
に、緑
をクリックして選択すれば color_v
にセットされる値が 'green'
に、青
をクリックして選択すれば color_v
にセットされる値が 'blue'
に変化するようになっていますし、選択されたアイテムに応じて左側に表示されるチェックマークの位置が変化するようになっています。
さらに、これらの 赤
と 緑
と 青
のアイテムがクリックされた際にも change_font
が実行されるようになっており、この change_font
の中で color_v
にセットされている値を取得し、Hello World
を表示しているラベルウィジェットに対して、取得した値に応じた文字色を設定するようにしています。そのため、これらがクリックされたタイミングで、Hello World
の文字列の色が変化することになります。
基本的には、チェックボタンメニューアイテムと使い方は似ていますので、チェックボタンとラジオボタンの性質の違いはありますが、そこを理解すれば、両方とも上手く使いこなすことができるようになると思います。
スポンサーリンク
セパレーターの追加
メニューグループへのセパレーターの追加は add_separator
メソッドで実施することができます。
セパレーターとは、アイテムとアイテムの間に挿入する区切り線のことになります。
add_separator
add_separator
メソッドの使い方は非常に単純で、このメソッドを追加したいメニューグループに引数なしで実行させればよいだけです。
メニューグループ.add_separator()
add_separator
の実行例
前述で示したスクリプトにおいては、下記のように edit_menu
に1回 add_separator
メソッドを実行させています。
edit_menu.add_cascade(label='色', menu=color_menu)
edit_menu.add_separator()
edit_menu.add_cascade(label='フォント', menu=font_menu)
上記のように add_separator
を実行させることで、色
のアイテムと フォント
のアイテムの間に区切り線が追加されることになります。
特に、これらの間に区切り線を追加した意味もないのですが、add_separator
の利用例を示すために add_separator
を実行させるようにしています。実際のアプリの開発時には、何か意味合いの大きく変わるアイテムの間に add_separator
で区切り線を追加してやるのが良いと思います。
以上が、メニューウィジェット(メニューグループ)の基本的な使い方となります。
基本的には、ここまで説明してきた内容を理解していただければ、メニューバーを自身で作成することができるようになるのではないかと思います。
ただし、ここまでの解説の中で説明していない Menu
のコンストラクタや add_xxxxx
メソッドに指定可能な引数や、メニューグループに実行させることのできるメソッドもありますので、ここからは、それらについて解説していきたいと思います。
正直言うと、メニューバーに関してはそんなに見た目にこだわる必要もないと思いますので、前述の通り、ここまで説明した内容を理解しておけば、実現したいメニューバーは自身で実現できると思います。なので、ここからは興味のある方のみ読み進めていただければ良いと思います。
メニューウィジェットの設定
では、ここからは、メニューウィジェットの設定について解説していきます。
他のウィジェット同様に、メニューウィジェットの見た目等の設定はコンストラクタ(tkinter.Menu()
)にキーワード引数を指定することで変更可能です。コンストラクタに指定可能なキーワード引数名は下記により確認することができます。
# menu:メニューウィジェット
print(menu.keys())
ここでは、私が動作を理解している設定に対する解説のみを行わせていただきます。具体的には、下記の設定について説明していきます。
- background
- foreground
- activebackground
- activeforeground
- selectcolor
- disabledforeground
- borderwidth
- font
- postcommand
- tearoff
- tearoffcommand
- relief
- cursor
- title
私の下記環境での実行結果をもとに説明していますが、環境によっては動きが異なるかもしれません
実際にご自身の環境で実行結果を確認していただくと、より確実に設定の効果を理解することができると思います
- OS:Windows 11
- Python:3.12
- Tkinter:8.6
メニューウィジェットの設定の注意点
メニューウィジェットの設定に関しては、いくつか注意点があるため、その点についてまず説明しておきます。
あくまでもメニューグループに対する設定である
Menu
クラスのコンストラクタのキーワード引数の指定によって変更可能なのは、あくまでもメニューグループに対する設定になります。個別のメニューアイテムに対する設定の変更に関しては、そのメニューアイテムを追加するときに実行する add_xxxxx
メソッドへのキーワード引数の指定によって実施する必要があります。add_xxxxx
メソッドに指定可能な引数に関しては、後述の add_xxxxx メソッドの引数 で説明していきます。
メインメニューグループには適用されない?
少なくとも私が試した感じでは、メインメニューグループの見た目等の設定の変更は不可でした。また、後述でも解説する「分離実行アイテム」も表示されないようになっています。
なので、もしかしたら環境依存かもしれませんが、メインメニューグループの設定は基本的に変更不可である可能性が高いです。以降の解説では、私の環境で動作確認済みの内容を説明していくのですが、これらはメインメニューグループ以外のメニューグループで動作確認を行っていますので、その点はご注意ください。
Mac では多くの設定が反映されない?
また、これはおそらくメニューグループだけでなく、メニューアイテムに対しても言えることだと思うのですが、以降で解説する設定は Mac の場合には無効であるものが多いです。少なくとも色の変更は不可でしたし、ウィンドウの分離等も不可のようでした。フォントサイズの変更は可能でした。
今後紹介する引数による設定は、Mac の場合は無効である可能性が高いので注意してください。
スポンサーリンク
background
では、ここからメニューウィジェットの設定を変更するキーワード引数の紹介を行っていきます。
まず、background
は、通常時のメニューグループの背景色を設定するキーワード引数となります。background
に関しては、略して bg
キーワード引数で指定することも可能です。
background
の値としては、色名やカラーコード等を指定することが可能です。
例えば下記のようにメニューグループを生成すれば、そのメニューグループの背景色が赤色に変化することになります。
menu = tkinter.Menu(
# 略
background='red'
)
foreground
foreground
は、通常時のメニューグループの文字色を設定するキーワード引数となります。foreground
に関しては、略して fg
キーワード引数で指定することも可能です。
foreground
の値としては、色名やカラーコード等を指定することが可能です。
例えば下記のようにメニューグループを生成すれば、そのメニューグループのメニューアイテムの文字色が緑色に変化することになります。
menu = tkinter.Menu(
# 略
foreground='green'
)
activebackground
activebackground
は、カーソルを合わせたメニューアイテムの背景色を設定するキーワード引数となります。
activebackground
の値としては、色名やカラーコード等を指定することが可能です。
例えば下記のようにメニューグループを生成すれば、そのメニューグループの背景色は通常時は赤色になりますが、カーソルを合わせた箇所のみ背景色が青色に変化することになります。
menu = tkinter.Menu(
# 略
background='red',
activebackground='blue'
)
スポンサーリンク
activeforeground
activeforeground
は、カーソルを合わせたメニューアイテムの文字色を設定するキーワード引数となります。
activeforeground
の値としては、色名やカラーコード等を指定することが可能です。
例えば下記のようにメニューグループを生成すれば、そのメニューグループの文字色は通常時は緑色になりますが、カーソルを合わせた箇所のみ文字色が白色に変化することになります。
menu = tkinter.Menu(
# 略
foreground='green',
activeforeground='white'
)
selectcolor
selectcolor
は、チェックマークの色を設定するキーワード引数となります。チェックボタンメニューアイテムやラジオボタンメニューアイテムに関しては、ON のアイテムや選択されたアイテムの左側にはチェックマークが表示されることになります。selectcolor
を指定することで、このチェックマークの色を変更することができます。
selectcolor
の値としては、色名やカラーコード等を指定することが可能です。
例えば下記のようにメニューグループを生成すれば、そのメニューグループ内に表示されるチェックマークの色がピンク色に変化することになります。
menu = tkinter.Menu(
# 略
selectcolor='pink'
)
disabledforeground
disabledforeground
は、無効化されたメニューアイテムの文字色を設定するキーワード引数となります。後述の state で説明する通り、メニューアイテムは state
引数によって無効化(クリック不可)することが可能です。disabledforeground
を指定することで、この無効化されたアイテムの文字色を変更することができます。
disabledforeground
の値としては、色名やカラーコード等を指定することが可能です。
例えば下記のようにメニューグループを生成すれば、そのメニューグループ内に表示される無効化されたアイテムの文字色が黄色に変化することになります。
menu = tkinter.Menu(
# 略
disabledforeground='yellow'
)
スポンサーリンク
font
font
は、メニューグループ内のメニューアイテムのアイテム名のフォントを設定するキーワード引数となります。
font
の値としては、tkinter.font.Font
のオブジェクトや、タプル等を指定することが可能です。フォントの指定の仕方に関しては下記ページでまとめていますので、必要に応じて下記ページを参照してください。
例えば下記のようにメニューグループを生成すれば、そのメニューグループ内に表示されるアイテムの文字のフォントサイズが 40
に変化することになります。
menu = tkinter.Menu(
# 略
font=('', 40)
)
postcommand
postcommand
は、そのメニューグループが表示された時に実行する処理を設定するキーワード引数となります。基本的には、メニューグループ表示時には単にそのグループが表示されるだけになりますが、postcommand
を指定することで、表示時に同時に何かしらの処理を実行することができるようになります。
postcommand
には、関数やメソッド等を指定することが可能です。ただし、関数に関しては引数なし、メソッドに関しては引数が self
のみである必要があります。
例えば下記のようにメニューグループを生成すれば、そのメニューグループが表示されるタイミングで Hello World
が出力されるようになります。
def print_hello():
print('Hello World')
menu = tkinter.Menu(
# 略
postcommand=print_hello
)
tearoff
tearfoff
は、そのメニューグループをメインウィンドウから分離可能とするかどうかを設定するキーワード引数となります。
分離可能と設定されている場合、そのメニューグループの先頭には分離実行アイテムが表示されることになります。そして、それをクリックすることで、メニューグループのメインウィンドウからの分離を行うことができます。
tearfoff
には BOOL 値(True
/ False
)を指定します。また、tearfoff
のデフォルト値は True
となります。ですが、メインメニューグループの場合は tearfoff
の指定に関わらず分離不可となります。
例えば下記のようにメニューグループを生成すれば、そのメニューグループはメインウィンドウからの分離は不可となります。
menu = tkinter.Menu(
# 略
tearoff=False
)
スポンサーリンク
tearoffcommand
teaoffcommand
は、そのメニューグループが分離された時、すなわち分離実行アイテムがクリックされたときに実行する処理を設定するキーワード引数となります。分離するためには tearfoff=True
が指定されている or tearfoff
引数が指定されていない必要があるため、tearfoff=False
が指定されている場合は、この引数は意味を持ちません。
tearoffcommand
には、関数やメソッド等を指定することが可能です。ただし、関数に関しては引数2つ、メソッドに関しては引数が self
+2つである必要があります。
例えば下記のようにメニューグループを生成すれば、そのメニューグループが分離されるタイミングで Hello World
が出力されるようになります。
def print_hello(a, b):
print('Hello World')
menu = tkinter.Menu(
# 略
tearoffcommand=print_hello
)
borderwidth
borderwidth
は、特に分離されたメニューグループの外枠の太さを設定するキーワード引数となります。
補足しておくと、おそらく分離前のメニューグループにも boarderwidth
を指定する効果はあります。ですが、私が試した感じだと、チェックマークの位置が変な位置に移動するだけで外枠の太さが変化することはありませんでした。つまり、boarderwidth
によって分離されたメニューグループの太さは適切に設定可能ですが、分離されていないメニューグループの表示が変になる可能性があります。なので、この引数は指定しない方が良いかなぁと思います。環境にもよるかもしれませんが…。
一応説明を続けると、borderwidth
には整数を指定します。単位はピクセルになると思います。
例えば下記のようにメニューグループを生成すれば、分離されたメニューグループの外枠の幅が 10
ピクセルに変化します。
menu = tkinter.Menu(
# 略
borderwidth=10
)
relief
relief
は、分離されたメニューグループの見た目を設定するキーワード引数となります。
relief
に指定可能な値や、それらの値を指定したときのウィジェットの見た目に関しては下記ページで解説していますので、詳しくは下記ページの relief をご参照ください(フレームの例で説明していますが、見た目の変化に関してはメニューグループにおいても同様になります)。
relief
の指定によってウィジェットの見た目が変化するのは外枠が太い場合です。ですが、前述の通り boarderwidth
を指定すると分離前のメニューグループに悪影響がありそうなので、この relief
の指定もオススメしません。見た目を変化させたい場合は、まずは relief
の指定と boarderwidth
の指定による分離前・分離後のメニューグループの見た目を確認してみてください。
例えば下記のようにメニューグループを生成すれば、分離されたメニューグループが浮き出したような見た目に変化します。
menu = tkinter.Menu(
# 略
borderwidth=10,
relief=tkinter.RAISED
)
スポンサーリンク
cursor
cursor
は、分離されたメニューグループにマウスカーソルを合わせたときのカーソルの見た目を設定する引数となります。
cursor
に指定可能な値に関しては、公式の下記ページで紹介されていますので、下記ページを参考にしていただければと思います。
https://tcl.tk/man/tcl8.6/TkCmd/cursors.htm
例えば下記のようにメニューグループを生成すれば、分離されたメニューグループにマウスカーソルを合わせたときのカーソルの見た目が「手」に変化します(Windows の場合は)。
menu = tkinter.Menu(
# 略
cursor='hand1'
)
title
title
は、分離されたメニューグループのウィンドウのタイトルを設定する引数となります。
title
には文字列を指定します。title
を指定しなかった場合は、分離されたメニューグループのウィンドウのタイトルには label
に指定した文字列が設定されるようになっています。
例えば下記のようにメニューグループを生成すれば、分離されたメニューグループのウィンドウのタイトルが menu
に変化します(Windows の場合は)。
menu = tkinter.Menu(
# 略
title='menu'
)
add_xxxxx
メソッドの引数
続いて、下記のメソッドに指定可能なキーワード引数について解説していきます。ちなみに、add_separator
に関しては指定可能な引数は無いです。
add_cacscade
add_command
add_checkbutton
add_radiobutton
具体的には、下記のキーワード引数の紹介を行っていきます。
- label
- menu
- command
- variable
- onvalue
- offvalue
- value
- indicatoron
- image
- compound
- accelerator
- state
- background
- foreground
- activebackground
- activeforeground
- selectcolor
- font
ここまでに説明してきたのはメニューウィジェット、すなわちメニューグループに対する設定となります。それに対し、ここから説明するのは、上記のメソッドへのキーワード引数の指定による「メニューグループの中の個別のメニューアイテムに対する設定」となります。
また、メニューウィジェット生成時に指定可能なキーワード引数と、上記のメソッドに指定可能なキーワード引数とは一部重複します。重複してキーワード引数が指定された場合は、上記のメソッド側に対するキーワード引数、すなわちメニューアイテムに対する設定が優先されることになります。例えば、メニューグループの背景色のみを緑色に設定した場合は、そのメニューグループの背景色は当然緑色になりますが、そのメニューグループに追加するメニューアイテムに対して背景色を白色に設定した場合、メニューアイテムに対する設定、つまり add_xxxxx
の引数による設定が優先されて、そのメニューアイテムの背景色は白色となります。
このあたりを理解した上でメニューウィジェットに対する設定およびメニューアイテムに対する設定を実施するようにしていただくと、意図したとおりの設定が行えるようになると思います。
また、ここから add_xxxxx
メソッドに指定可能なキーワード引数の紹介を行っていきますが、各種キーワード引数が add_xxxxx
のメソッドの全てに指定可能というわけではありません。そのため、次のような表を使って、各メソッドに指定可能なキーワード引数を示すようにしていきたいと思います。
雰囲気で理解していただけると思いますが、念のため説明しておくと、cascade
は add_cascade
、command
は add_command
、check
は add_checkbutton
、radio
は add_radiobutton
をそれぞれ表しており、〇が付いているメソッドは、そのキーワード引数が指定可能、×が付いているメソッドは、そのキーワード引数が指定不可であることを示しています。
cascade |
command |
check |
radio |
〇 | × | × | 〇 |
スポンサーリンク
label
では、add_xxxxx
メソッドに指定可能なキーワード引数を紹介していきます。
まず、label
は、追加するメニューアイテムの表示名を設定するキーワード引数となります。
label
は全メソッドに対して指定可能なキーワード引数となります。
cascade |
command |
check |
radio |
〇 | 〇 | 〇 | 〇 |
label
の値には文字列を指定します。
また、label
の値を指定しなかった場合、add_cascade
の場合は表示名が ()
、それ以外の場合は空白となるようです。
例えば下記のように add_command
を実行すれば、実行したメニューウィジェットに表示名が 開く
であるコマンドメニューアイテムが追加されることになります。
# menu:メニューウィジェット
menu.add_command(
# 略
label='開く'
)
menu
は、追加するメニューグループを設定するキーワード引数となります。
メニューグループを追加することのできるメソッドは add_cascade
のみであるため、この menu
が指定できるのは add_cascade
のみとなります。
cascade |
command |
check |
radio |
〇 | × | × | × |
menu
の値にはメニューグループ、すなわちメニューウィジェットを指定します。
例えば下記のように add_cascade
を実行すれば、実行したメニューウィジェットに file_menu
というメニューグループが追加されることになります。
# menu,file_menu:メニューウィジェット
menu.add_command(
# 略
menu=file_menu
)
command
command
は、追加するメニューアイテムがクリックされた時に実行する処理を設定するキーワード引数となります。
command
は全メソッドに対して指定可能なキーワード引数となります。特に add_command
は、クリックされた時に何らかの処理を実行するメニューアイテムを追加するためのメソッドとなるため、add_command
に関しては基本的に command
の指定は必須であると考えて良いです。
cascade |
command |
check |
radio |
〇 | 〇 | 〇 | 〇 |
command
には、関数やメソッド等を指定することが可能です。ただし、関数に関しては引数なし、メソッドに関しては引数が self
のみである必要があります。
例えば下記のように add_command
を実行すれば、追加されたメニューアイテムがクリックされた時に Hello World
が出力されるようになります。
def print_hello():
print('Hello World')
# menu:メニューウィジェット
menu.add_command(
# 略
command=print_hello
)
スポンサーリンク
variable
variable
は、追加するメニューアイテムと連動するウィジェット変数を設定するキーワード引数となります。
variable
は add_checkbutton
と add_radiobutton
に指定可能なキーワード引数となります。
cascade |
command |
check |
radio |
× | × | 〇 | 〇 |
variable
にはウィジェット変数を指定することが可能です。メニューウィジェットの使い方 でも説明したように、チェックボタンメニューアイテムであれば、そのメニューアイテムのチェックが ON / OFF (チェックマーク有 / 無)のどちらの状態であるかをウィジェット変数から判別できるようになります。また、ラジオボタンメニューアイテムであれば、複数のラジオボタンメニューアイテムの内、どれが選択されているのかをウィジェット変数から判別できるようになります。
さらに、これも メニューウィジェットの使い方 で説明したように、ラジオボタンメニューアイテムの場合は、同じウィジェット変数が variable
に指定されているものが同一グループのアイテムとして扱われるようになります。
このウィジェット変数の詳細に関しては下記ページで詳細を解説していますので、ウィジェット変数の役割やウィジェット変数の使い方等を知りたい方は下記ページをご参照ください。
Tkinterの使い方:ウィジェット変数について解説【StringVar・BooleanVar・IntVar・DoubleVar】チェックボタンメニューアイテムの場合は、チェックの ON / OFF の2つの状態が管理できれば良いので、add_checkbutton
の variable
には tkinter.BooleanVar()
で生成したウィジェット変数を指定すればよいです。
それに対し、ラジオボタンメニューアイテムの場合は、3つ以上を含む複数のアイテムのうちのどれが選択されているかを判別できるようにする必要があるので、他のウィジェット変数を指定することが多いと思います。例えば、メニューウィジェットの使い方 においては、赤
・緑
・青
の3つのアイテムが選択されているときにはウィジェット変数に 'red'
・'green'
・'blue'
の文字列をそれぞれセットするようにするため、これらのラジオボタンメニューアイテムを追加する時に実行する add_radiobutton
の variable
には tkinter.StringVar()
で生成したウィジェットを指定するようにしています。要は、アイテムが選択された時にセットしたい値に応じてウィジェット変数の種類を変更する必要があるので、この点には注意してください。
例えば下記のように add_checkbutton
を実行すれば、追加されたチェックボタンメニューアイテムが ON のときは check_v
に True
が、OFF の時は check_v
に False
がセットされるようになります。また、check_v.get()
によって check_v
にセットされている値が取得できるため、そのチェックボタンメニューアイテムが ON / OFF のどちらであるかは print_checked
関数のような処理で判別することが可能となります。
def print_checked():
if check_v.get():
print('チェックON')
else:
print('チェックOFF')
# 初期値がFalseのウィジェット変数生成
check_v = tkinter.BooleanVar(value=False)
# menu:メニューウィジェット
menu.add_checkbutton(
# 略
variable=check_v
)
また、追加されたチェックボタンメニューアイテムのチェックが ON / OFF それぞれの時にウィジェット変数にセットされる値は、後述の onvalue
と offvalue
で設定可能ですし、追加されたラジオボタンメニューアイテムが選択されているときにウィジェット変数にセットされる値は、後述の value
で設定可能です。
onvalue
/ offvalue
onvalue
は追加するチェックボタンメニューアイテムのチェックが ON のときにウィジェット変数にセットする値を、offvalue
は追加するチェックボタンメニューアイテムのチェックが OFF のときにウィジェット変数にセットする値を設定するキーワード引数になります。
これらはチェックボタンメニューアイテムに対する設定となるため、チェックボタンメニューアイテムを追加する add_checkbutton
にのみ指定可能なキーワード引数となります。
cascade |
command |
check |
radio |
× | × | 〇 | × |
ウィジェット変数にセットできる値はウィジェット変数の種類によって異なります。また、ウィジェット変数は前述の variable
で指定することになるため、onvalue
と offvalue
には「variable
で指定するウィジェット変数にセット可能な値」を指定する必要があります。例えば variable
に tkinter.StringVar()
で生成したウィジェット変数を指定するのであれば、onvalue
と offvalue
には文字列を指定する必要があることになります。
onvalue
のデフォルト値は True
、offvalue
のデフォルト値は False
です。そのため、これらを指定しない場合は、variable
に tkinter.BooleanVar()
で生成したウィジェット変数を指定する必要があります。逆に言えば、variable
に tkinter.BooleanVar()
で生成したウィジェット変数を指定してやれば、onvalue
と offvalue
の指定は不要となります。
例えば下記のように add_checkbutton
を実行すれば、追加されたチェックボタンメニューアイテムのチェックが ON のときは check_v
に 'ON'
という文字列が、OFF の時は check_v
に 'OFF'
という文字列がセットされるようになります。ただし、check_v
には文字列がセットされることになるため、check_v
には tkinter.StringVar()
で生成したウィジェット変数を指定する必要があります。また、check_v.get()
によって check_v
にセットされている値が取得できるため、そのチェックボタンメニューアイテムのチェックが ON / OFF のどちらであるかは print_checked
関数のような処理で判別することが可能となります。
def print_checked():
if check_v.get() == 'ON':
print('チェックON')
else:
print('チェックOFF')
# 初期値が'OFF'のウィジェット変数生成
check_v = tkinter.StringVar(value='OFF')
# menu:メニューウィジェット
menu.add_checkbutton(
# 略
variable=check_v,
onvalue='ON',
offvalue='OFF'
)
value
value
は、追加するラジオボタンメニューアイテムが選択されているときにウィジェット変数にセットする値を設定するキーワード引数になります。
value
はラジオボタンメニューアイテムに対する設定となるため、ラジオボタンメニューアイテムを追加する add_radiobutton
にのみ指定可能なキーワード引数となります。また、value
は variable
とセットで指定する必要があります。
cascade |
command |
check |
radio |
× | × | × | 〇 |
onvalue
や offvalue
と同様に、value
には「variable
で指定するウィジェット変数にセット可能な値」を指定する必要があります。
variable
を指定する場合は、add_radiobutton
には必ず value
も指定する必要があります。また、複数のラジオボタンメニューアイテムのうち、どれが選択中であるかをウィジェット変数にセットされる値から判別できるようにするためには、同じ variable
を指定する add_radiobutton
では、それぞれで異なる値を value
に指定する必要があります。
例えば下記のように add_radiobutton
を実行すれば、表示名が 赤
・緑
・青
の3つのラジオボタンメニューアイテムが追加され、これらは同じ variable=color_v
が指定されているため、同じグループのアイテムとした使われます。また、それぞれの value
の指定により、赤
のアイテムが選択されると color_v
に 'red'
が、緑
のアイテムが選択されると color_v
に 'green'
が、青
のアイテムが選択されると color_v
に 'blue'
がそれぞれセットされることになるため、print_selected
関数のように color_v.get
で取得される値によって、選択中のアイテムが判別できることになります。
def print_selected():
if color_v.get() == 'red':
print('赤が選択中')
elif color_v.get() == 'green':
print('緑が選択中')
else:
print('青が選択中')
# 初期値が'red'のウィジェット変数生成
color_v = tkinter.StringVar(value='red')
# menu:メニューウィジェット
menu.add_radiobutton(
# 略
label='赤',
variable=color_v,
value='red'
)
menu.add_radiobutton(
# 略
label='緑',
variable=color_v,
value='green'
)
menu.add_radiobutton(
# 略
label='青',
variable=color_v,
value='blue'
)
スポンサーリンク
indicatoron
indicatoron
は、追加するチェックボタンメニューアイテムやラジオボタンメニューアイテムのチェックマークの表示の有無を設定するキーワード引数になります。
indicatoron
は add_checkbutton
と add_radiobutton
に指定可能なキーワード引数となります。
cascade |
command |
check |
radio |
× | × | 〇 | 〇 |
indicatoron
には True
or False
を指定します。indicatoron
のデフォルト値は True
となります。
チェックボタンメニューアイテムに関しては ON の場合に、ラジオボタンメニューアイテムに関しては選択中の場合に、アイテムの左側にチェックマークが表示されるようになっていますが、indicatoron=False
を指定することで、そのチェックマークを非表示にすることができます。
例えば下記のように add_checkbutton
を実行すれば、追加されたチェックボタンメニューアイテムのチェックマークを非表示にすることができます。
# menu:メニューウィジェット
menu.add_checkbutton(
# 略
indicatoron=False
)
image
image
は、追加するメニューアイテムの表示を画像に変更するキーワード引数になります。
image
は全メソッドに対して指定可能なキーワード引数となります。
cascade |
command |
check |
radio |
〇 | 〇 | 〇 | 〇 |
前述の通り、追加したメニューアイテムは label
に指定した文字列で表示されることになります。ですが、image
を指定することで、追加したメニューを文字列ではなく画像で表示することが可能となります。
label
と image
の両方を指定した場合は、image
が優先されて画像が表示されることになります。label
に指定した文字列と image
に指定した画像の両方を表示するようにしたい場合は、後述の compound
引数を指定する必要があります。
また、image
の値には Tkinter の画像オブジェクトを指定する必要があります。この Tkinter の画像オブジェクトに関しては下記ページでまとめていますので、詳細は下記ページを参照してください。
例えば下記のように add_command
を実行すれば、追加されたコマンドメニューアイテムが cat.png
の画像として表示されることになります。
photo = tkinter.PhotoImage(
file='cat.png',
)
# menu:メニューウィジェット
menu.add_command(
# 略
image=photo
)
compound
compound
は、追加するメニューアイテムの表示を画像+文字列に変更するキーワード引数になります。
compound
は全メソッドに対して指定可能なキーワード引数となります。
cascade |
command |
check |
radio |
〇 | 〇 | 〇 | 〇 |
compound
を指定することで、追加するメニューアイテムを label
に指定した文字列+ image
に指定した画像で表示することができるようになります。
compound
には下記の5つの値を指定することが可能です。
tkinter.TOP
:label
に指定した文字列の上側にimage
に指定した画像を表示するtkinter.BOTTOM
:label
に指定した文字列の下側にimage
に指定した画像を表示するtkinter.LEFT
:label
に指定した文字列の左側にimage
に指定した画像を表示するtkinter.RIGHT
:label
に指定した文字列の右側にimage
に指定した画像を表示するtkinter.NONE
:文字列 or 画像の一方のみを表示する(label
とimage
の両方が指定されていればimage
を優先)
基本的には、label
に指定した文字列に対して image
に指定した画像をどちら側に表示するのかを上記の値で指定することになります。例えば、tkinter.BOTTOM
を指定すれば、label
に指定した文字列の下側(ボトム側)に image
に指定した画像が表示されることになります。
また、compound
のデフォルト値は tkinter.NONE
となります。そのため、compound
を指定しない場合は、メニューアイテムは文字列 or 画像のどちらか一方で表示されることになります。
例えば下記のように add_command
を実行すれば、追加されたコマンドメニューアイテムが 設定
という文字列+ cat.png
の画像として表示されることになります。compoud=tkinter.BOTTOM
を指定しているため、このコマンドメニューアイテムは 設定
という文字列の下側に cat.png
の画像が配置された形で表示されることになります。
photo = tkinter.PhotoImage(
file='cat.png',
)
# menu:メニューウィジェット
menu.add_command(
# 略
label='設定',
image=photo,
compoud=tkinter.BOTTOM
)
スポンサーリンク
accelerator
accelerator
は、追加するメニューアイテムの項目名の横に追加で表示する文字列を設定するキーワード引数になります。
accelerator
は全メソッドに対して指定可能なキーワード引数となります。
cascade |
command |
check |
radio |
〇 | 〇 | 〇 | 〇 |
accelerator
には文字列を指定します。
この accelerator
は各種メニューアイテムのショートカットキーを示すために利用されることが多いと思います(というか、それ以外に使い道が思いつかない…)。例えば、accelerator='(Alt+s)'
を指定すれば、追加されるメニューアイテムの項目名の右側に (Alt+s)
が表示され、そのアイテムのショートカットキーが Alt
キーと s
キーの同時押しであることをユーザーに示すことができるようになります。
ただし、この accelerator
はショートカットキーの表示をするだけで、accelerator
を指定しただけでショートカットキーが設定されるというわけではないので注意してください。ショートカットキーとして機能させるためには、bind
メソッドや invoke
メソッドの実行が必要となります。このあたりは後述の invoke で説明します。
例えば下記のような処理を実行すれば、add_command
で追加されたメニューアイテムの項目名 設定
の右に (Alt+s)
が表示されるようになります。
# menu:メニューウィジェット
menu.add_command(
# 略
label='設定',
accelerator='(Alt+s)'
)
state
state
は、追加するメニューアイテムの状態を設定するキーワード引数となります。例えば、そのメニューアイテムを無効化(クリック不可)にするようなことも可能です。
state
は全メソッドに対して指定可能なキーワード引数となります。
cascade |
command |
check |
radio |
〇 | 〇 | 〇 | 〇 |
state
には下記の3つの値が指定可能ですが、おそらくメニューアイテムに関しては tkinter.NORMAL
と tkinter.ACTIVE
を指定した場合は、両方とも同じ状態(有効状態)になると思います。
tkinter.NORMAL
:有効化tkinter.DISABLED
:無効化tkinter.ACTIVE
:有効化?
また、tkinter.DISABLED
で無効化したメニューアイテムの文字色は、メニューウィジェット生成時に disabledforeground
を指定することで変更可能です。詳細に関しては disabledforeground を参照してください。
例えば下記のように add_cascade
を実行すれば、追加されたメニューアイテムはクリック不可となります。
# menu:メニューウィジェット
menu.add_cascade(
# 略
state=tkinter.DISABLED
)
background
background
に関してはメニューウィジェットの設定の方で説明しましたので、詳細に関しては background を参照してください。
background
は全メソッドに対して指定可能なキーワード引数となります。
cascade |
command |
check |
radio |
〇 | 〇 | 〇 | 〇 |
スポンサーリンク
foreground
foreground
に関してもメニューウィジェットの設定の方で説明しましたので、詳細に関しては foreground を参照してください。
foreground
は全メソッドに対して指定可能なキーワード引数となります。
cascade |
command |
check |
radio |
〇 | 〇 | 〇 | 〇 |
activebackground
activebackground
に関してもメニューウィジェットの設定の方で説明しましたので、詳細に関しては activebackground を参照してください。
activebackground
は全メソッドに対して指定可能なキーワード引数となります。
cascade |
command |
check |
radio |
〇 | 〇 | 〇 | 〇 |
activeforeground
activeforeground
に関してもメニューウィジェットの設定の方で説明しましたので、詳細に関しては activeforeground を参照してください。
activeforeground
は全メソッドに対して指定可能なキーワード引数となります。
cascade |
command |
check |
radio |
〇 | 〇 | 〇 | 〇 |
スポンサーリンク
selectcolor
selectcolor
に関してもメニューウィジェットの設定の方で説明しましたので、詳細に関しては selectcolor を参照してください。
selectcolor
は、チェックマークの表示されるチェックボタンメニューアイテムを追加する add_checkbutton
と add_radiobutton
に対してのみ指定可能なキーワード引数となります。
cascade |
command |
check |
radio |
× | × | 〇 | 〇 |
font
font
に関してもメニューウィジェットの設定の方で説明しましたので、詳細に関しては font を参照してください。
font
は全メソッドに対して指定可能なキーワード引数となります。
cascade |
command |
check |
radio |
〇 | 〇 | 〇 | 〇 |
Menu
クラスのメソッド
最後に Menu
クラスに用意されたメソッドについて紹介していきたいと思います。
ここでは、Menu
クラス特有のメソッド&私が動作を理解している下記の4種類のメソッドのみを紹介させていただきます。
スポンサーリンク
add_xxxxx
まず、ここまでにも紹介してきた下記の5つのメソッドが挙げられます。
add_cacscade
add_command
add_checkbutton
add_radiobutton
add_separator
これらは、メニューウィジェット(メニューグループ)の末尾に各種要素を追加するメソッドとなります。なので、これらの要素は実行した順序で上から順に表示されることになります。
insert_xxxxx
それに対し、下記の5つのメソッドは、追加する位置を指定して各種要素をメニューグループに追加するメソッドとなります。
insert_cacscade
insert_command
insert_checkbutton
insert_radiobutton
insert_separator
これらの第1引数(or index
引数)に整数を指定することで、メニューグループの好きな位置に各種要素を追加することが可能です。この引数には 0
以上の整数を指定する必要があり、メニュグループの一番上側が 0
に対応しています。
ただし、分離実行アイテムの上側には要素追加することは不可のようなので、その点には注意してください。
その他の引数に関しては add_xxxxx
と同様であるため、詳細に関しては add_xxxxx のメソッド を参照してください。
post
post
メソッドは、任意の座標にメニューグループを表示するメソッドとなります。
これを利用して、例えば右クリックメニューを表示するようなことが可能となります。
post
メソッドには第1引数(or x
引数)にメニューグループを表示する x
座標、第2引数(or y
引数)にメニューグループを表示する y
座標を指定して実行します。
メニューウィジェット.post(x 座標, y 座標)
例えば、下記のようなスクリプトを実行すれば、右クリック実行時に menu
が表示されるようになります。環境によっては、右クリックが <ButtonPress-3>
と対応していない可能性があるので、必要に応じてこの部分は、あなたの使用環境に合わせて修正してください。
import tkinter
def right_menu(event):
# menuをクリックされた位置に表示
menu.post(event.x_root, event.y_root)
def file_open():
print('file_open')
def file_save(x):
print('file_save')
# メインウィンドウを作成
app = tkinter.Tk()
app.geometry('400x300')
# メニューグループを作成
menu = tkinter.Menu(
app,
)
menu.add_command(label='開く', command=file_open)
menu.add_command(label='保存', command=file_save)
# 右クリック時に実行する関数をbind
app.bind('<ButtonPress-3>', right_menu)
# メインループ
app.mainloop()
ちなみに、クリック等のイベントに関しては下記ページでまとめていますので、イベントに関して知りたい方は別途下記ページを参照してください。
Tkinterの使い方:イベント処理を行うスポンサーリンク
invoke
invoke
は、メニューアイテムのクリックを行うメソッドになります。
これを利用することで、各種メニューアイテムに対するショートカットキーを設定することが可能です。
invoke
メソッドには第1引数(or index
引数)にクリックしたいメニューグループ内の位置を指定します。この位置は、各種メニューグループに追加されたメニューアイテム(分離実行アイテムを含む)に対して上から順に割り当てられた整数で、一番上が 0
となります。
メニューウィジェット.invoke(クリックしたい位置)
例えば、下記のようなスクリプトを実行すれば、Alt
キーと o
キーの同時押しによって項目名が 開く
のメニューアイテムがクリックされることになり、print('file_open')
が実行されることになります。また、Alt
キーと c
キーの同時押しによって項目名が チェック
のメニューアイテムがクリックされることになり、この項目のチェックの ON / OFF が切り替わることになります。
import tkinter
def click_open(event):
sub_menu.invoke(0)
def click_check(event):
sub_menu.invoke(1)
def file_open():
print('file_open')
# メインウィンドウを作成
app = tkinter.Tk()
app.geometry('400x300')
# メニューグループを作成
menu = tkinter.Menu(
app,
)
sub_menu = tkinter.Menu(
menu,
tearoff=False
)
# メインメニューを設定
app.config(menu=menu)
menu.add_cascade(label='サブメニュー', menu=sub_menu)
sub_menu.add_command(label='開く', command=file_open, accelerator='(Alt+o)')
sub_menu.add_checkbutton(label='チェック', accelerator='(Alt+c)')
# Alt+oが押された時に実行する関数をbind
app.bind('<Alt-o>', click_open)
# Alt+cが押された時に実行する関数をbind
app.bind('<Alt-c>', click_check)
# メインループ
app.mainloop()
上記の例のように、各メニューアイテムに割り当てたショートカットキーの表示に関しては、add_xxxxx
に対して accelerator
引数を利用して表示するのが良いと思います。
まとめ
このページでは、Tkinter のメニューウィジェットについて解説しました!
このメニューウィジェットを利用することで、Tkinter で開発するアプリにメニューバーを表示することができるようになります。また、右クリックメニュー等も実現することが可能です。
メニューウィジェットは「グループ」であることを意識すると使い方が分かりやすくになると思います。このグループにアイテムだけでなくグループを追加することで、複数の階層のメニューバーを実現することが可能です。
是非、ご自身でメニューバー付きのウェブアプリを開発し、その動きを確認しながらメニューウィジェットへの理解を深めてみてください!
オススメ参考書(PR)
Tkinter に興味がある方には下記のPythonでつくる ゲーム開発 入門講座がオススメです。
Tkinter をゲーム開発を通して「楽しく学ぶ」ことができます。Python 入門者、Tkinter 入門者の方にオススメです。