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追記。 :
スクリプトソースがサンプルとして冗長に感じたので、少しだけ簡単にして差し替えた。
[ ツッコむ ]
以上、1 日分です。