【Python】オプションメニューを使った処理の制御【Tkinter】
オプションメニューを使った処理の制御
Tkinterでオプションメニューを使った処理の制御をする
値を取得する
ウィジェット変数
ウィジェット変数とは
- ウィジェットの状態を制御するために使用されるオブジェクト
- ウィジェットが表示される際に、ウィジェット変数に格納された値がウィジェットに反映される
- ユーザーがウィジェットを操作した場合、その変更がウィジェット変数にも反映される
よく使われるウィジェット変数
- StringVar:文字列を保持
- IntVar:整数を保持
- DoubleVar:浮動小数点を保持
- BooleanVar:真偽値を保持
選択しているメニューの値を取得する
import tkinter as tk
# ====================
# 値を取得する関数
# ====================
def print_selected_value() -> None:
selected_value = selected_menu_var.get()
print(f"取得値:{selected_value}")
# --------------------
# GUIの設定
# --------------------
# 基本設定
app = tk.Tk()
app.title("オプションメニューの設定値を取得")
app.geometry("350x200")
# --------------------
# オプションメニュー
# --------------------
# オプションメニューの値を保持する変数と初期値の設定
selected_menu_var = tk.StringVar(value="未選択")
# メニュー本体
menu = tk.OptionMenu(
app,
selected_menu_var,
"メニュー1",
"メニュー2",
"メニュー3",
)
# --------------------
# ボタン
# --------------------
# 関数を実行するボタン
submit_btn = tk.Button(app, text="値を取得する", command=print_selected_value)
# --------------------
# 配置
# --------------------
menu.pack(anchor="center", padx=20, pady=5)
submit_btn.pack(pady=40)
# ====================
# アプリの実行
# ====================
app.mainloop()
起動画面

任意のメニューを選択して値を取得する

実行結果
取得値:メニュー3
CustomTkinter版
import customtkinter as ctk
# ====================
# 値を取得する関数
# ====================
def print_selected_value() -> None:
selected_value = selected_menu_var.get()
print(f"取得値:{selected_value}")
# --------------------
# GUIの設定
# --------------------
# 基本設定
app = ctk.CTk()
app.title("オプションメニューの設定値を取得")
app.geometry("350x200")
# --------------------
# オプションメニュー
# --------------------
# オプションメニューの値を保持する変数と初期値の設定
selected_menu_var = ctk.StringVar(value="未選択")
# メニュー本体
menu = ctk.CTkOptionMenu(
app,
values=[
"メニュー1",
"メニュー2",
"メニュー3",
],
variable=selected_menu_var,
)
# --------------------
# ボタン
# --------------------
# 関数を実行するボタン
submit_btn = ctk.CTkButton(app, text="値を取得する", command=print_selected_value)
# --------------------
# 配置
# --------------------
menu.pack(anchor="center", padx=20, pady=5)
submit_btn.pack(pady=40)
# ====================
# アプリの実行
# ====================
app.mainloop()
起動画面

任意のメニューを選択して値を取得する

実行結果
取得値:メニュー3
メニューを選択した時に値を取得する
import tkinter as tk
# ===================================
# メニュー選択時に値を取得する関数
# ===================================
def on_menu_selected(choice) -> None:
print("メニュー選択で取得した値:", choice)
# ===================================
# ボタンから値を取得する関数
# ===================================
def print_selected_value() -> None:
selected_value = selected_menu_var.get()
print(f"ボタン押下で取得した値:{selected_value}")
# --------------------
# GUIの設定
# --------------------
# 基本設定
app = tk.Tk()
app.title("オプションメニューの設定値を取得")
app.geometry("350x200")
# --------------------
# オプションメニュー
# --------------------
# オプションメニューの値を保持する変数と初期値の設定
selected_menu_var = tk.StringVar(value="未選択")
# メニュー本体
menu = tk.OptionMenu(
app,
selected_menu_var,
"メニュー1",
"メニュー2",
"メニュー3",
command=on_menu_selected, # メニュー選択の都度関数を実行する
)
# --------------------
# ボタン
# --------------------
# 関数を実行するボタン
submit_btn = tk.Button(app, text="値を取得する", command=print_selected_value)
# --------------------
# 配置
# --------------------
menu.pack(anchor="center", padx=20, pady=5)
submit_btn.pack(pady=40)
# ====================
# アプリの実行
# ====================
app.mainloop()
起動画面

任意のメニュー選択結果(1 → 2 → 3の順に選択)
メニュー選択で取得した値: メニュー1
メニュー選択で取得した値: メニュー2
メニュー選択で取得した値: メニュー3
ボタン押下による実行結果
ボタン押下で取得した値:メニュー3
CustomTkinter版
import customtkinter as ctk
# ===================================
# メニュー選択時に値を取得する関数
# ===================================
def on_menu_selected(choice) -> None:
print("メニュー選択で取得した値:", choice)
# ===================================
# ボタンから値を取得する関数
# ===================================
def print_selected_value() -> None:
selected_value = selected_menu_var.get()
print(f"ボタン押下で取得した値:{selected_value}")
# --------------------
# GUIの設定
# --------------------
# 基本設定
app = ctk.CTk()
app.title("オプションメニューの設定値を取得")
app.geometry("350x200")
# --------------------
# オプションメニュー
# --------------------
# オプションメニューの値を保持する変数と初期値の設定
selected_menu_var = ctk.StringVar(value="未選択")
# メニュー本体
menu = ctk.CTkOptionMenu(
app,
values=[
"メニュー1",
"メニュー2",
"メニュー3",
],
variable=selected_menu_var,
command=on_menu_selected, # メニュー選択の都度関数を実行する
)
# --------------------
# ボタン
# --------------------
# 関数を実行するボタン
submit_btn = ctk.CTkButton(app, text="値を取得する", command=print_selected_value)
# --------------------
# 配置
# --------------------
menu.pack(anchor="center", padx=20, pady=5)
submit_btn.pack(pady=40)
# ====================
# アプリの実行
# ====================
app.mainloop()
起動画面

任意のメニュー選択結果(1 → 2 → 3の順に選択)
メニュー選択で取得した値: メニュー1
メニュー選択で取得した値: メニュー2
メニュー選択で取得した値: メニュー3
ボタン押下による実行結果
ボタン押下で取得した値:メニュー3
メニューの更新
メニューの選択内容で別メニューの選択肢を変える
- 都道府県メニュー の選択内容で 市区町村メニュー の選択肢が変わるサンプル
- TkinterのOptionMenuは業務に不向きなのでComboboxを使用している
- アプリ実行前に同期処理をしておかないと市区町村メニューが空欄で起動してしまうので注意
import tkinter as tk
from tkinter import ttk
# メニューAとメニューBの表示リスト
PREF_TO_CITIES = {
'東京都': ['千代田区', '新宿区', '渋谷区'],
'神奈川県': ['横浜市', '川崎市', '相模原市'],
'大阪府': ['大阪市', '堺市', '吹田市'],
}
# =============================================
# メニューAの選択でメニューBの内容を更新する
# =============================================
def on_pref_changed(_event=None) -> None:
selected_pref = pref_var.get()
cities = PREF_TO_CITIES.get(selected_pref, [])
# Bの候補を差し替え
city_menu['values'] = cities
# 候補があれば先頭、なければブランクにする
if cities:
city_var.set(cities[0])
city_menu.current(0)
else:
city_var.set('')
city_menu.set('') # 表示も空にする
# --------------------
# GUIの設定
# --------------------
# 基本設定
app = tk.Tk()
app.title('オプションメニューの設定値による制御')
app.geometry('350x200')
# 2列目を伸縮させる
app.grid_columnconfigure(1, weight=1)
# --------------------
# オプションメニュー
# --------------------
# メニューA:都道府県
pref_var = tk.StringVar(value='東京都')
pref_menu = ttk.Combobox(
app,
textvariable=pref_var,
values=list(PREF_TO_CITIES.keys()),
state='readonly', # 手入力を禁止
)
# 変更イベント(選択が変わったとき)
pref_menu.bind('<>', on_pref_changed)
# メニューB:市区町村
city_var = tk.StringVar()
city_menu = ttk.Combobox(
app,
textvariable=city_var,
values=[],
state='readonly',
)
# --------------------
# ラベル
# --------------------
# 都道府県ラベル
label_pref = ttk.Label(app, text='【都道府県】')
# 市区町村ラベル
label_city = ttk.Label(app, text='【市区町村】')
# --------------------
# 配置
# --------------------
# グリッド1行目に配置
label_pref.grid(row=0, column=0, padx=12, pady=(24, 16), sticky='w')
pref_menu.grid(row=0, column=1, padx=12, pady=(24, 16), sticky='ew')
# グリッド2行目に配置
label_city.grid(row=1, column=0, padx=12, pady=16, sticky='w')
city_menu.grid(row=1, column=1, padx=12, pady=16, sticky='ew')
# ====================
# アプリの実行
# ====================
# 初期同期でメニューBを埋めておく
on_pref_changed()
# アプリの実行
app.mainloop()
起動画面

都道府県メニューを選択すると市区町村メニューが変化する
東京都選択時

神奈川県選択時

CustomTkinter版
import customtkinter as ctk
# メニューAとメニューBの表示リスト
PREF_TO_CITIES = {
'東京都': ['千代田区', '新宿区', '渋谷区'],
'神奈川県': ['横浜市', '川崎市', '相模原市'],
'大阪府': ['大阪市', '堺市', '吹田市'],
}
# =============================================
# メニューAの選択でメニューBの内容を更新する
# =============================================
def on_pref_changed(selected_pref: str) -> None:
cities = PREF_TO_CITIES.get(selected_pref, [])
# Bの候補を差し替え
city_menu.configure(values=cities)
# 候補があれば先頭、なければブランクにする
if cities:
city_var.set(cities[0])
else:
city_var.set('')
# --------------------
# GUIの設定
# --------------------
# 基本設定
app = ctk.CTk()
app.title('オプションメニューの設定値による制御')
app.geometry('350x200')
# 2列目を伸縮させる
app.grid_columnconfigure(1, weight=1)
# --------------------
# オプションメニュー
# --------------------
# メニューA:都道府県
pref_var = ctk.StringVar(value='東京都')
pref_menu = ctk.CTkOptionMenu(
app,
values=list(PREF_TO_CITIES.keys()),
variable=pref_var,
command=on_pref_changed, # 変更時に呼ばれる(選択した都道府県を渡す)
)
# メニューB:市区町村(初期は東京都に合わせる)
city_var = ctk.StringVar()
city_menu = ctk.CTkOptionMenu(
app,
values=[],
variable=city_var
)
# --------------------
# ラベル
# --------------------
# 都道府県ラベル
label_pref = ctk.CTkLabel(app, text='【都道府県】')
# 市区町村ラベル
label_city = ctk.CTkLabel(app, text='【市区町村】')
# --------------------
# 配置
# --------------------
# グリッド1行目に配置
label_pref.grid(row=0, column=0, padx=12, pady=(24, 16), sticky='w')
pref_menu.grid(row=0, column=1, padx=12, pady=(24, 16), sticky='ew')
# グリッド2行目に配置
label_city.grid(row=1, column=0, padx=12, pady=16, sticky='w')
city_menu.grid(row=1, column=1, padx=12, pady=16, sticky='ew')
# ====================
# アプリの実行
# ====================
# 初期同期でメニューBを埋めておく
on_pref_changed(pref_var.get())
app.mainloop()
起動画面

都道府県メニューを選択すると市区町村メニューが変化する
東京都選択時

神奈川県選択時
