tkinter.Menu【メニューバー・ポップアップメニュー】
メモ ( メニューバーの作成 例 ポップアップメニューの作成・表示 例 処理設定 例 ショートカット・アクセラレータ 例 ) 仮想イベント 例 オプション ウィジェットオプション 要素オプション メソッド 例
メモ
- メニューの作成
- tkinter.Menu:従来のウィジェット
- 下記を作成
- メニューバー:トップレベルウィンドウのメニュー部
- ポップアップメニュー:右クリック等で表示するメニュー
- プルダウンメニュー:メニューバーの要素・各種メニューの階層要素
- Menubutton【メニューボタン】・OptionMenu【オプションメニュー (ドロップダウンリスト)】のドロップダウン部としても内部的に使用
- 処理設定〔 例 〕
- 要素オプションの command【処理関数】を指定
- チェックボタン要素・ラジオボタン要素のチェック状態の取得・設定:
variable【値用ウィジェット変数】のウィジェット変数を取得・設定 - 要素の無効化:要素オプションの state【状態】を tk.DISABLED【無効状態】に設定
- ショートカット・アクセラレータ〔 例 〕
- ショートカット:要素オプションの underline【下線の文字位置】指定 (実装不要)
- アクセラレータ:要素オプションの accelerator【右側の文字列】指定
bind_all【イベント関連付け (アプリケーション)】等で実装
- 提供される基本操作
- [Esc]キー:メニュー選択解除
- [Space]・[Enter / Return]キー:選択要素処理
- 上下キー:上下の要素に移動
- 左右キー:左右の要素に移動
外部リンク
仮想イベント
- イベント設定〔 例 〕
- bind( )【イベント関連付け】で設定 〔イベント関連メソッド 〕
仮想イベント | 説明 | 備考 |
---|---|---|
<<MenuSelect>> | アクティブ要素の変更で発生 引数 eventイベントオブジェクト | index(tk.ACTIVE) では正しい要素が取得できない為、 root.call(event.widget, "index", "active") で取得 |
オプション
メモ
- オプションの設定方法
- コンストラクタで辞書型引数 (tk のみ)・キーワード引数として指定
- オプション名を辞書インデックスとして指定 ( widget ['オプション名'] )
- config・configure【オプション設定・取得】で辞書型引数・キーワード引数として指定
- オプション関連のメソッド
- オプション関連メソッド
- Style.configure( ):Style に設定した値
- 注) 実装依存 (各種ドキュメントに相違があり)
オプション 一覧
ウィジェットオプション | |||
---|---|---|---|
個別 | tk | ttk | 説明 |
postcommand | ● | メニュー表示時に呼び出される関数 (環境により表示と呼び出しの順序が相違) | |
tearoff | ● | メニューの切り離し可否 (環境依存) (True:切り取り線のクリックで切り離し可 / False:切り離し不可) | |
tearoffcommand | ● | 切り離し時に呼び出される関数 | |
title | ● | 切り離されたメニューのタイトル (省略:階層要素のラベル) | |
type | ○ | 種類 ・'menubar':メニューバー ・'tearoff':切り離されたメニュー ・'normal':その他メニュー | |
テキスト・外観 | tk | ttk | 説明 |
font | ● | フォント (tkinter.Font) | |
relief | ● | 外観 | |
borderwidth (bd) | ● | 境界線の幅 | |
activeborderwidth | ● | アクティブ要素の境界線の幅 | |
色 関連 | tk | ttk | 説明 |
background (bg) | ● | 背景色 | |
foreground (fg) | ● | 前景色 | |
activebackground | ● | アクティブ要素の背景色 | |
activeforeground | ● | アクティブ要素の前景色 | |
disabledforeground | ● | 無効要素の前景色 | |
selectcolor | ● | チェック記号の前景色 | |
共通 | tk | ttk | 説明 |
cursor | ● | マウスカーソル名 (切り離された場合のみ有効) | |
name | ○ | インスタンス名 (省略:自動命名) 先頭は小文字・ドットは不可 / フルパスで一意 〔 インスタンス識別 〕 | |
takefocus | ● | [Tab]キー等でのフォーカス移動の有無〔フォーカス〕 ・'' (空文字列):自動設定 ・False:なし (スキップ) ・True:あり (タブストップ) |
凡例
●:各種方法で指定可能
○:コンストラクタでのみ指定可能
▲:config( ) 等でのみ指定可能
Config:コンストラクタ 及び config( ) 等で指定可能
Style:Style でのみ指定可能
Method:メソッドの引数で指定
Default:デフォルト値
:テーマ依存
○:コンストラクタでのみ指定可能
▲:config( ) 等でのみ指定可能
Config:コンストラクタ 及び config( ) 等で指定可能
Style:Style でのみ指定可能
Method:メソッドの引数で指定
Default:デフォルト値
:テーマ依存
要素オプション | ||
---|---|---|
個別 | 対象要素 | 説明 |
accelerator | 右側の文字列 (通常はアクセラレータ:実装は別途必要) | |
columnbreak | 列の追加 | |
command | Check Command Radio | 処理関数 (引数:なし) |
hidemargin | ||
state | 状態 ・tk.NORMAL:通常状態 ・tk.ACTIVE:アクティブ状態 ・tk.DISABLED:無効状態 | |
テキスト・画像 | 対象要素 | 説明 |
font | フォント (tkinter.Font) | |
label | ラベル | |
compound | テキストと画像の合成 | |
bitmap | ||
image | ||
色 関連 | 対象要素 | 説明 |
background | 背景色 | |
foreground | 前景色 | |
activebackground | アクティブ時の背景色 | |
activeforeground | アクティブ時の前景色 | |
selectcolor | Check Radio | チェック記号の前景色 |
階層要素 関連 | 対象要素 | 説明 |
menu | Cascade | サブメニュー (メニューオブジェクト) |
チェックボタン・ラジオボタン要素 関連 | 対象要素 | 説明 |
indicatoron | Check Radio | チェック記号の表示有無 |
offvalue | Check | オフの値 (デフォルト:False) |
onvalue | Check | オンの値 (デフォルト:True) |
selectimage | Check Radio | |
value | Radio | 選択されたときの値 (グループ内で一意) 空文字列:label【ラベル】を使用 |
variable | Check Radio | 値用ウィジェット変数 (ラジオボタン要素:共有するとグループ化) |
共通 | 対象要素 | 説明 |
underline | 下線の文字位置 (0~) (ショートカットキー用:実装は不要 command【処理関数】を呼び出し) |
凡例
Cascade:階層要素が対象
Check:チェックボタン要素が対象
Command:コマンド要素が対象
Radio:ラジオボタン要素が対象
対象省略:各種要素が対象
Check:チェックボタン要素が対象
Command:コマンド要素が対象
Radio:ラジオボタン要素が対象
対象省略:各種要素が対象
色 | 説明 |
---|---|
'色名' | 色名:'red'・'green'・'blue'・'gray0'~'gray100'・'system~' 等 下記参照 Tcl8.6/Tk8.6 - Tk Commands - colors (同名色でも HTML5:カラー定義 と定義に差異あり) |
'#RGB' | 16進 4ビット |
'#RRGGBB' | 16進 8ビット |
'#RRRGGGBBB' | 16進 12ビット |
'#RRRRGGGGBBBB' | 16進 16ビット |
マウスカーソル名の詳細 ( cursor )
マウスカーソル名 | 説明 |
---|---|
'マウスカーソル名' | 下記参照 ('arrow'・'wait' 等) Tcl8.6/Tk8.6 - Tk Commands - cursors (英語) Tkinter 8.5 reference: a GUI for Python - Cursors (英語) |
テキストと画像の合成の詳細 ( compound )
指定値 | 説明 (テキスト対しての画像位置) |
---|---|
'text' ttk | テキストのみ表示 |
'image' ttk | 画像のみ表示 |
NONE | テキストの代わりに画像表示 |
BOTTOM | 画像をテキストの下側に表示 |
TOP | 画像をテキストの上側に表示 |
LEFT | 画像をテキストの左側に表示 |
RIGHT | 画像をテキストの右側に表示 |
CENTER | 画像をテキストの上に表示 |
外観の詳細 ( relief )
外観 | 説明 |
---|---|
FLAT | フラット |
GROOVE | 凹み枠 |
RAISED | 隆起 (凸) |
RIDGE | 隆起枠 (凸枠) |
SOLID | 実線 |
SUNKEN | 凹み |
メソッド
コンストラクタ | 備考 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Menu(master=None, cnf={ } , **kw) | コンストラクタ master親 (tkinter.Tk【トップレベルウィンドウ】・親メニュー) cnf (辞書型引数)オプション kw (キーワード引数)オプション | ||||||||||||
固有メソッド | 備考 | ||||||||||||
共通 | 要素下記で要素指定 ・数値インデックス (0~) ・tk.ACTIVE:アクティブ要素 ・tk.END:最終要素 (index( )【要素インデックス・要素数の取得】 ・insert_cascade( )【階層要素挿入】等:最終要素の次) ・tk.LAST:最終要素 (tk.ENDと同等) ・tk.NONE:要素なし (アクティブ要素の解除等で使用) ・'@y':y座標の要素 ・上記以外:パターン | ||||||||||||
activate(index) | アクティブ要素の設定 index要素 | ||||||||||||
add_cascade(cnf={ } , **kw) | 階層要素の追加 cnf (辞書型引数) 要素オプション kw (キーワード引数)要素オプション | ||||||||||||
add_checkbutton(cnf={ } , **kw) | チェックボタン要素の追加 cnf (辞書型引数) 要素オプション kw (キーワード引数)要素オプション | ||||||||||||
add_command(cnf={ } , **kw) | コマンド要素の追加 cnf (辞書型引数) 要素オプション kw (キーワード引数)要素オプション | ||||||||||||
add_radiobutton(cnf={ } , **kw) | ラジオボタン要素の追加 cnf (辞書型引数) 要素オプション kw (キーワード引数)要素オプション | ||||||||||||
add_separator(cnf={ } , **kw) | セパレータ要素の追加 cnf (辞書型引数) 要素オプション kw (キーワード引数)要素オプション | ||||||||||||
delete(index1, index2=None) | 要素削除 index1開始要素 index2終了要素 (省略:1要素削除) | ||||||||||||
entrycget(index, option) | 要素オプション取得 戻り値要素オプション index要素 option要素オプション名 | ||||||||||||
entryconfig(index, cnf=None, **kw) entryconfigure( 同上 ) | 要素オプション取得・設定 戻り値 (要素オプション指定:設定)なし 戻り値 (要素オプション未指定:取得)全要素オプション (辞書型)
cnf (辞書型引数) 要素オプション kw (キーワード引数)要素オプション | ||||||||||||
index(index) | 要素位置インデックス取得 戻り値要素位置インデックス (0~ / None:なし) index要素 (END:最終項目) | ||||||||||||
insert_cascade(index, cnf={ } , **kw) | 階層要素の挿入 index要素 cnf (辞書型引数) 要素オプション kw (キーワード引数)要素オプション | ||||||||||||
insert_checkbutton(index, cnf={ } , **kw) | チェックボタン要素の挿入 index要素 cnf (辞書型引数) 要素オプション kw (キーワード引数)要素オプション | ||||||||||||
insert_command(index, cnf={ } , **kw) | コマンド要素の挿入 index要素 cnf (辞書型引数) 要素オプション kw (キーワード引数)要素オプション | ||||||||||||
insert_radiobutton(index, cnf={ } , **kw) | ラジオボタン要素の挿入 index要素 cnf (辞書型引数) 要素オプション kw (キーワード引数)要素オプション | ||||||||||||
insert_separator(index, cnf={ } , **kw) | セパレータ要素の挿入 index要素 cnf (辞書型引数) 要素オプション kw (キーワード引数)要素オプション | ||||||||||||
invoke(index) | 処理実行 ・command【処理関数】あり:処理関数実行 ・チェックボタン要素:オンオフ切換 ・ラジオボタン要素:要素選択 戻り値 (command【処理関数】あり)処理関数の戻り値 戻り値 (command【処理関数】なし)なし index要素 | ||||||||||||
post(x, y) | メニュー表示 x表示x座標 (ルートからの相対) y表示y座標 (ルートからの相対) | ||||||||||||
tk_popup(x, y, entry="") | メニュー表示 (要素インデックス指定) xx座標 yy座標 entry要素インデックス (0~) | ||||||||||||
type(index) | 要素種類取得 戻り値要素種類
| ||||||||||||
unpost() | メニュー非表示 (環境依存) | ||||||||||||
xposition(index) | 要素x座標取得 戻り値相対x座標 index要素 | ||||||||||||
yposition(index) | 要素y座標取得 戻り値相対y座標 index要素 | ||||||||||||
共通メソッド (抜粋) 〔詳細はリンク先〕 | 備考 | ||||||||||||
cget( 'option' ) widget['option'] | オプション値 取得 下の構文はオプション値の設定も可 | ||||||||||||
config( ~ ) configure( ~ ) | オプション 設定・取得 | ||||||||||||
pack( ~ ) | 配置 (パック形式) | ||||||||||||
grid( ~ ) | 配置 (グリッド形式) | ||||||||||||
place( ~ ) | 配置 (座標形式) |
例
メニューバーの作成
import tkinter as tk
# トップレベルウィンドウ作成
root = tk.Tk()
root.geometry("500x250")
# メニューバー
menubar = tk.Menu(root)
root.config(menu=menubar)
# [MenuA]
menu_a = tk.Menu(
menubar,
tearoff=False,
)
# [MenuA] - [CommandA-1]
menu_a.add_command(
label="CommandA-1",
# command=,
)
# [MenuA] - [CommandA-2]
menu_a.add_command(
label="CommandA-2",
# command=,
)
# [CascadeA-1]
cascade_a_1 = tk.Menu(
menu_a,
tearoff=False,
)
# [CascadeA-1] - [Check-1]
var_check_1 = tk.BooleanVar(value=True)
cascade_a_1.add_checkbutton(
label="Check-1",
variable=var_check_1,
)
# [CascadeA-1] - [Check-2]
var_check_2 = tk.BooleanVar(value=True)
cascade_a_1.add_checkbutton(
label="Check-2",
variable=var_check_2,
)
# [CascadeA-1] - [Separator]
cascade_a_1.add_separator()
# [CascadeA-1] - [Radio-1]
var_radio = tk.IntVar(value=1)
cascade_a_1.add_radiobutton(
label="Radio-1",
value=1,
variable=var_radio,
)
# [CascadeA-1] - [Radio-2]
cascade_a_1.add_radiobutton(
label="Radio-2",
value=2,
variable=var_radio,
)
# [CascadeA-1] - [Separator]
cascade_a_1.add_separator()
# [MenuA] - [CascadeA_1]
menu_a.add_cascade(
label="CascadeA-1",
menu=cascade_a_1,
)
# [CascadeA-2]
cascade_a_2 = tk.Menu(
cascade_a_1,
tearoff=False,
)
# [CascadeA-2] - [Command-1] ~ [Command-6]
cascade_a_2.add_command(
label="Command-1",
# command=,
)
cascade_a_2.add_command(
label="Command-2",
# command=,
)
cascade_a_2.add_command(
label="Command-3",
# command=,
)
cascade_a_2.add_command(
label="Command-4",
columnbreak=True,
# command=,
)
cascade_a_2.add_command(
label="Command-5",
# command=,
)
cascade_a_2.add_command(
label="Command-6",
# command=,
)
# [CascadeA-1] - [CascadeA-2]
cascade_a_1.add_cascade(
label="CascadeA-2",
menu=cascade_a_2,
)
# [MenuB]
menu_b = tk.Menu(
menubar,
tearoff=False,
)
# [MenuB] - [Exit]
menu_b.add_command(
label="Exit",
command=quit,
)
# [メニューバー] - [MenuA] ~ [MenuB]
menubar.add_cascade(label="MenuA", menu=menu_a)
menubar.add_cascade(label="MenuB", menu=menu_b)
# メインループ
root.mainloop()
ポップアップメニューの作成・表示
import tkinter as tk
# ポップアップメニュー表示
def show_popupmenu(event):
popupmenu.post(event.x_root, event.y_root)
# トップレベルウィンドウ作成
root = tk.Tk()
root.geometry("500x250")
# ポップアップメニュー
popupmenu = tk.Menu(
root,
tearoff = False,
)
# [ポップアップメニュー] - [Command-1]
popupmenu.add_command(
label="Command-1",
# command=,
)
# [ポップアップメニュー] - [Command-2]
popupmenu.add_command(
label="Command-2",
# command=,
)
# 右クリックイベント関連付け
root.bind("<Button-3>", show_popupmenu)
# メインループ
root.mainloop()
処理設定
import tkinter as tk
# [CommandA-1] 処理
def command_a_1():
command_common("CommandA-1")
# 共通処理
def command_common(msg):
check_1 = var_check_1.get()
check_2 = var_check_2.get()
radio = var_radio.get()
str = f'{msg} (Check-1:{check_1} / Check-2:{check_2} / Radio:{radio})'
var_msg.set(str)
# トップレベルウィンドウ作成
root = tk.Tk()
root.geometry("500x250")
# Label
var_msg = tk.StringVar(value="var_msg")
label = tk.Label(
root,
textvariable=var_msg,
relief=tk.SUNKEN,
anchor=tk.W,
)
label.pack(side=tk.BOTTOM, fill=tk.X)
# メニューバー
menubar = tk.Menu(root)
root.config(menu=menubar)
# [MenuA]
menu_a = tk.Menu(
menubar,
tearoff=False,
)
# [MenuA] - [CommandA-1]
menu_a.add_command(
label="CommandA-1",
command=command_a_1,
)
# [MenuA] - [CommandA-2]
menu_a.add_command(
label="CommandA-2",
command=lambda: command_common("CommandA-2"),
)
# [CascadeA-1]
cascade_a_1 = tk.Menu(
menu_a,
tearoff=False,
)
# [CascadeA-1] - [Check-1]
var_check_1 = tk.BooleanVar(value=True)
cascade_a_1.add_checkbutton(
label="Check-1",
variable=var_check_1,
command=lambda: command_common("Check-1"),
)
# [CascadeA-1] - [Check-2]
var_check_2 = tk.BooleanVar(value=False)
cascade_a_1.add_checkbutton(
label="Check-2",
variable=var_check_2,
command=lambda: command_common("Check-2"),
)
# [CascadeA-1] - [Separator]
cascade_a_1.add_separator()
# [CascadeA-1] - [Radio-1]
var_radio = tk.IntVar(value=1)
cascade_a_1.add_radiobutton(
label="Radio-1",
value=1,
variable=var_radio,
command=lambda: command_common("Radio-1"),
)
# [CascadeA-1] - [Radio-2]
cascade_a_1.add_radiobutton(
label="Radio-2",
value=2,
variable=var_radio,
command=lambda: command_common("Radio-2"),
)
# [CascadeA-1] - [Separator]
cascade_a_1.add_separator()
# [MenuA] - [CascadeA-1]
menu_a.add_cascade(
label="CascadeA-1",
menu=cascade_a_1,
)
# [MenuA] - [Exit]
menu_a.add_command(
label="Exit",
command=quit,
)
# [CascadeA-2]
cascade_a_2 = tk.Menu(
cascade_a_1,
tearoff=False,
)
# [CascadeA-2] - [Command-1] ~ [Command-6]
cascade_a_2.add_command(
label="Command-1",
command=lambda: command_common("Command-1"),
)
cascade_a_2.add_command(
label="Command-2",
command=lambda: command_common("Command-2"),
)
cascade_a_2.add_command(
label="Command-3",
command=lambda: command_common("Command-3"),
)
cascade_a_2.add_command(
label="Command-4",
command=lambda: command_common("Command-4"),
columnbreak=True,
)
cascade_a_2.add_command(
label="Command-5",
command=lambda: command_common("Command-5"),
state=tk.DISABLED,
)
cascade_a_2.add_command(
label="Command-6",
command=lambda: command_common("Command-6"),
)
# [CascadeA-1] - [CascadeA-2]
cascade_a_1.add_cascade(
label="CascadeA-2",
menu=cascade_a_2,
)
# [MenuB]
menu_b = tk.Menu(
menubar,
tearoff=False,
)
# [MenuB] - [CommandB]
menu_b.add_command(
label="CommandB",
command=lambda: command_common("CommandB"),
)
# [MenuB] - [Exit]
menu_b.add_command(
label="Exit",
command=quit,
)
# [メニューバー] - [MenuA] ~ [MenuB]
menubar.add_cascade(label="MenuA", menu=menu_a)
menubar.add_cascade(label="MenuB", menu=menu_b)
# メインループ
root.mainloop()
import tkinter as tk
# ポップアップメニュー表示
def show_popupmenu(event):
popupmenu.post(event.x_root, event.y_root)
# コマンド処理
def command_common(msg):
var_msg.set(msg)
# トップレベルウィンドウ作成
root = tk.Tk()
root.geometry("500x250")
# Label
var_msg = tk.StringVar(value="var_msg")
label = tk.Label(
root,
textvariable=var_msg,
relief=tk.SUNKEN,
anchor=tk.W,
)
label.pack(side=tk.BOTTOM, fill=tk.X)
# ポップアップメニュー
popupmenu = tk.Menu(
root,
tearoff=False,
)
# [ポップアップメニュー] - [Command-1]
popupmenu.add_command(
label="Command-1",
command=lambda: command_common("Command-1"),
)
# [ポップアップメニュー] - [Command-2]
popupmenu.add_command(
label="Command-2",
command=lambda: command_common("Command-2"),
)
# [ポップアップメニュー] - [Exit]
popupmenu.add_command(
label="Exit",
command=quit,
)
# 右クリックイベント関連付け
root.bind("<Button-3>", show_popupmenu)
# メインループ
root.mainloop()
ショートカット・アクセラレータ
import tkinter as tk
# [CommandA-1] 処理
def command_a_1(event=None):
var_msg.set("CommandA_1")
# [CommandA-2] 処理
def command_a_2(event=None):
var_msg.set("CommandA_2")
# トップレベルウィンドウ作成
root = tk.Tk()
root.geometry("500x250")
# Label
var_msg = tk.StringVar(value="var_msg")
label = tk.Label(
root,
textvariable=var_msg,
relief=tk.SUNKEN,
anchor=tk.W,
)
label.pack(side=tk.BOTTOM, fill=tk.X)
# メニューバー
menubar = tk.Menu(root)
root.config(menu=menubar)
# [MenuA]
menu_a = tk.Menu(
menubar,
tearoff=False,
)
# [MenuA] - [CommandA-1]
menu_a.add_command(
label="CommandA-1",
command=command_a_1,
underline=9, # CommandA-[1]
accelerator="Ctrl+X",
)
root.bind_all("<Control-x>", command_a_1)
# [MenuA] - [CommandA-2]
menu_a.add_command(
label="CommandA-2",
command=command_a_2,
underline=9, # CommandA-[2]
accelerator="Shift+Ctrl+Y",
)
root.bind_all("<Shift-Control-Y>", command_a_2)
# [MenuA] - [Exit]
menu_a.add_command(
label="Exit",
command=quit,
)
# [メニューバー] - [MenuA]
menubar.add_cascade(label="MenuA", menu=menu_a)
# メインループ
root.mainloop()
仮想イベント
import tkinter as tk
# イベント処理
def menu_select_event(event):
index = root.call(event.widget, "index", "active")
# (NG) index = menu_a.index(tk.ACTIVE)
msg = str(index) + ": " + menu_a.entrycget(index, "label")
var_label.set(msg)
# トップレベルウィンドウ作成
root = tk.Tk()
root.geometry("500x250")
# Label
var_label = tk.StringVar(value="var_label")
label = tk.Label(
root,
textvariable=var_label,
relief=tk.SUNKEN,
anchor=tk.W,
)
label.pack(side=tk.BOTTOM, fill=tk.X)
# メニューバー
menubar = tk.Menu(root)
root.config(menu=menubar)
# [MenuA]
menu_a = tk.Menu(
menubar,
tearoff=False,
)
# [MenuA] - [CommandA-1]
menu_a.add_command(
label="CommandA-1",
#command=,
)
# [MenuA] - [CommandA-2]
menu_a.add_command(
label="CommandA-2",
#command=,
)
# [メニューバー] - [MenuA]
menubar.add_cascade(label="MenuA", menu=menu_a)
# bind
menu_a.bind("<<MenuSelect>>", menu_select_event)
# メインループ
root.mainloop()