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

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

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

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

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

任意のメニュー選択結果(1 → 2 → 3の順に選択)
メニュー選択で取得した値: メニュー1
メニュー選択で取得した値: メニュー2
メニュー選択で取得した値: メニュー3
ボタン押下による実行結果
ボタン押下で取得した値:メニュー3
CustomTkinter版
import customtkinter as ctk
# -----------------------------------
# メニュー選択時に値を取得する関数
# -----------------------------------
def optionmenu_callback(choice) -> None:
print('メニュー選択で取得した値:', choice)
# -----------------------------------
# ボタンから値を取得する関数
# -----------------------------------
def get_selected_value() -> None:
selected_value = optionmenu_var.get()
print(f'ボタン押下で取得した値:{selected_value}')
# GUIの基本設定
app = ctk.CTk()
app.title('オプションメニューの設定値を取得')
app.geometry('350x200')
# オプションメニューの値を保持する変数と初期値の設定
optionmenu_var = ctk.StringVar(value='未選択')
# オプションメニューの作成
optionmenu = ctk.CTkOptionMenu(
app,
values=[
'メニュー1',
'メニュー2',
'メニュー3',
],
variable=optionmenu_var,
command=optionmenu_callback # メニュー選択の都度関数を実行する
)
optionmenu.pack(anchor='center', padx=20, pady=5)
# 関数を実行するボタン
btn = ctk.CTkButton(master=app, text='値を取得する', command=get_selected_value)
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 = {
'東京都': ['千代田区', '新宿区', '渋谷区'],
'神奈川県': ['横浜市', '川崎市', '相模原市'],
'大阪府': ['大阪市', '堺市', '吹田市'],
}
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', # 手入力を禁止
)
# 都道府県ラベル
label_pref = ttk.Label(app, text='【都道府県】')
# メニューB:市区町村
city_var = tk.StringVar()
city_menu = ttk.Combobox(
app,
textvariable=city_var,
values=[],
state='readonly',
)
# 市区町村ラベル
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')
# 変更イベント(選択が変わったとき)
pref_menu.bind('<>', on_pref_changed)
# 初期同期でメニューBを埋めておく
on_pref_changed()
# アプリの実行
app.mainloop()
起動画面

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

神奈川県選択時

CustomTkinter版
import customtkinter as ctk
# ---------------------------------------------
# メニューAの選択でメニューBの内容を更新する
# ---------------------------------------------
PREF_TO_CITIES = {
'東京都': ['千代田区', '新宿区', '渋谷区'],
'神奈川県': ['横浜市', '川崎市', '相模原市'],
'大阪府': ['大阪市', '堺市', '吹田市'],
}
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, # 変更時に呼ばれる(選択した都道府県を渡す)
)
# 都道府県ラベル
label_pref = ctk.CTkLabel(app, text='【都道府県】')
# メニューB:市区町村(初期は東京都に合わせる)
city_var = ctk.StringVar()
city_menu = ctk.CTkOptionMenu(
app,
values=[],
variable=city_var
)
# 市区町村ラベル
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()
起動画面

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

神奈川県選択時
