mieki256's diary



2022/12/05(月) [n年前の日記]

#1 [python] tkinterのCheckbuttonを勉強中その2

Python + tkinter の Checkbutton(チェックボックス)について勉強中。

複数の Checkbutton を並べて、それぞれのチェック状態をマウスクリックで変更した際、どの Checkbutton が変更されたのか判別したい。要するに、以下のような動作を実現したい。

checkbutton_py_ss01.gif


ということで、以下のようなスクリプトになった。動作確認環境は Windows10 x64 22H2 + Python 3.9.13。

_checkbutton.py
_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()

少し解説。
関数に与える引数は、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) )

参考ページ。 :

2022/12/06追記。 :

スクリプトソースがサンプルとして冗長に感じたので、少しだけ簡単にして差し替えた。

以上です。

過去ログ表示

Prev - 2022/12 - Next
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project