2022/12/05(月) [n年前の日記]
#1 [python] tkinterのCheckbuttonを勉強中その2
Python + tkinter の Checkbutton(チェックボックス)について勉強中。
複数の Checkbutton を並べて、それぞれのチェック状態をマウスクリックで変更した際、どの Checkbutton が変更されたのか判別したい。要するに、以下のような動作を実現したい。
ということで、以下のようなスクリプトになった。動作確認環境は Windows10 x64 22H2 + Python 3.9.13。
_checkbutton.py
_checkbutton_simple.py.txt
少し解説。
関数に与える引数は、Checkbutton毎に違う値にする。そのあたり、以下のように2つの書き方ができる。らしい。
1つは、lambda を使う方法。
もう1つは、partial を使う方法。partial を import して使う。
ちなみに、以下のような書き方をしても動かない。
複数の Checkbutton を並べて、それぞれのチェック状態をマウスクリックで変更した際、どの Checkbutton が変更されたのか判別したい。要するに、以下のような動作を実現したい。
ということで、以下のようなスクリプトになった。動作確認環境は Windows10 x64 22H2 + Python 3.9.13。
_checkbutton_simple.py.txt
import tkinter as tk from functools import partial CHK_LIST = [ ["Apple", True], ["Orange", True], ["Lemon", False], ["Peach", False], ["Banana", True], ["strawberry", True], ] def click_cb(n): """Click Checkbutton.""" global cbs, cb_values, msg name = cbs[n].cget("text") value = cb_values[n].get() msg.set(f"{name} (id={n}) is {value}") def click_button(): """Toggle Checkbuttons value.""" global cb_values for cb in cb_values: if True: v = cb.get() cb.set(not v) else: cb.toggle() root = tk.Tk() root.title("Test Checkbutton") root.geometry("400x400") # create Label msg = tk.StringVar(value="Message") lbl = tk.Label(root, textvariable=msg, borderwidth=2, relief="ridge", font=("Arial", "18", "normal")) # create Button button = tk.Button(root, text="Toggle", command=click_button) # create Checkbuttons cb_values = [] cbs = [] for i, d in enumerate(CHK_LIST): def_text, def_value = d # reserve Checkbutton value cb_values.append(tk.BooleanVar(value=def_value)) # create Checkbutton cb = tk.Checkbutton(root, text=def_text, variable=cb_values[i], command=lambda i=i: click_cb(i), # command = partial(click_cb, i), # command = click_cb(i), # command = lambda: click_cb(i), ) cbs.append(cb) cbs[i].pack() lbl.pack() button.pack() root.mainloop()
少し解説。
- tkinter.Checkbutton を呼んでチェックボックスWidgetを生成する際、command を指定すれば、チェック状態が変わった時に呼ばれる関数を指定できる。
- その関数に引数を与えて呼ぶことで、どの Checkbutton から呼ばれたかを判別できる。
関数に与える引数は、Checkbutton毎に違う値にする。そのあたり、以下のように2つの書き方ができる。らしい。
1つは、lambda を使う方法。
cb = tk.Checkbutton(root, text=def_text, variable=cb_values[i], command=lambda i=i: click_cb(i) )
もう1つは、partial を使う方法。partial を import して使う。
from functools import partial # ... cb = tk.Checkbutton(root, text=def_text, variable=cb_values[i], command = partial(click_cb, i) )
ちなみに、以下のような書き方をしても動かない。
cb = tk.Checkbutton(root, text=def_text, variable=cb_values[i], command = click_cb(i) )
cb = tk.Checkbutton(root, text=def_text, variable=cb_values[i], command = lambda: click_cb(i) )
◎ 参考ページ。 :
_python - Checkbuttons and buttons: using lambda - Stack Overflow
_Python Tkinterの大量のボタンをpartialを使って楽に設置 - Qiita
_Python:tkinter.(ttk.)Checkbutton【チェックボックス ウィジェット】 - リファレンス メモ
_Tkinter ボタンコマンドに引数を渡す方法 | Delft スタック
_Python: functools.partial() で関数やメソッドを部分適用する - CUBE SUGAR CONTAINER
_Python Tkinterの大量のボタンをpartialを使って楽に設置 - Qiita
_Python:tkinter.(ttk.)Checkbutton【チェックボックス ウィジェット】 - リファレンス メモ
_Tkinter ボタンコマンドに引数を渡す方法 | Delft スタック
_Python: functools.partial() で関数やメソッドを部分適用する - CUBE SUGAR CONTAINER
◎ 2022/12/06追記。 :
スクリプトソースがサンプルとして冗長に感じたので、少しだけ簡単にして差し替えた。
[ ツッコむ ]
以上です。