【Python】スイッチを使った処理の制御【Tkinter】

Python,Tkinter

スイッチを使った処理の制御

CustomTkinterでスイッチを使った処理の制御をする


ウィジェットを制御する

ウィジェット変数

ウィジェット変数とは

  • ウィジェットの状態を制御するために使用されるオブジェクト
  • ウィジェットが表示される際に、ウィジェット変数に格納された値がウィジェットに反映される
  • ユーザーがウィジェットを操作した場合、その変更がウィジェット変数にも反映される

よく使われるウィジェット変数

  • StringVar:文字列を保持
  • IntVar:整数を保持
  • DoubleVar:浮動小数点を保持
  • BooleanVar:真偽値を保持

スイッチの on / off で部品の活性・非活性を制御する

  • スイッチ off で入力値をクリアし、操作不可にする
  • スイッチ on で操作可能にし、メニュー系は初期値を入れる
  • Tkinterには対応するウィジェットがないため割愛
import customtkinter as ctk

def on_switch_changed(var: ctk.StringVar, target) -> None:
    """CTkSwitch の状態に応じて、対になる入力ウィジェットを制御する

    Parameters
        var : ctk.StringVar
            スイッチの状態を保持する変数('on' / 'off')
        target : CTk widget
            スイッチと対になる入力UI(Entry または OptionMenu / ComboBox)

    Behavior
        - OFF : 入力値をクリアし、操作不可にする
        - ON  : 操作可能にし、メニュー系は初期値を入れる
    """
    # スイッチが off になっているかどうかの真偽値を格納する
    is_off = (var.get() == 'off')

    # インスタンスで Entry かどうかを判定する
    if isinstance(target, ctk.CTkEntry):
        if is_off:
            target.delete(0, ctk.END)
            target.configure(state='disabled')
        else:
            target.configure(state='normal')

    # インスタンスで メニュー系 かどうかを判定する
    elif isinstance(target, (ctk.CTkOptionMenu, ctk.CTkComboBox)):
        menu_var = target.cget('variable')  # StringVar
        if is_off:
            if menu_var is not None:
                # 未選択状態にする
                menu_var.set('')
            target.configure(state='disabled')
        else:
            target.configure(state='normal')
            # 先頭表示メニューに戻す(初期値代入でも問題なし)
            menu_var.set(menu_1.cget('values')[0])

# --------------------
# GUIの設定
# --------------------
# 基本設定
app = ctk.CTk()
app.title('スイッチでウィジェットを制御する')
app.geometry('350x200')
# 1列目を伸縮させる
app.grid_columnconfigure(0, weight=1)

# --------------------
# 入力フィールド
# --------------------
entry_1 = ctk.CTkEntry(app)

# --------------------
# 対になるスイッチ
# --------------------
entry_switch_var = ctk.StringVar(value='on')
entry_switch = ctk.CTkSwitch(
    app,
    text='off | on',
    variable=entry_switch_var,
    onvalue='on',
    offvalue='off',
    command=lambda: on_switch_changed(entry_switch_var, entry_1)
)

# --------------------
# オプションメニュー
# --------------------
menu_var = ctk.StringVar(value='A')
menu_1 = ctk.CTkOptionMenu(app, values=['A', 'B', 'C'], variable=menu_var)

# --------------------
# 対になるスイッチ
# --------------------
menu_switch_var = ctk.StringVar(value='on')
menu_switch = ctk.CTkSwitch(
    app,
    text='off | on',
    variable=menu_switch_var,
    onvalue='on',
    offvalue='off',
    command=lambda: on_switch_changed(menu_switch_var, menu_1)
)

# --------------------
# 配置
# --------------------
# グリッド1行目に配置
entry_1.grid(row=0, column=0, padx=10, pady=15, sticky='ew')
entry_switch.grid(row=0, column=1, padx=10, pady=15, sticky='w')

# グリッド2行目に配置
menu_1.grid(row=1, column=0, padx=10, pady=15, sticky='ew')
menu_switch.grid(row=1, column=1, padx=10, pady=15, sticky='w')

# ====================
# アプリの実行
# ====================
app.mainloop()

起動画面

入力ウィジェットを埋める

スイッチで非活性化する