【コード付】Tkinterで使われるbindとは?bindの仕組みを交えて解説
今回はTkinterで使われるbindに関して、bindの仕組みを交えて徹底解説いたします。なんとなくbindを使っていた、bindの仕組みを理解して、知見を深めたい方へおすすめです。ぜひ最後までご一読ください。
- そもそもTkinterで使われるbindとは?
- tkinterで使われるbind関数の定義
- bind関数を削除する
- 関数に渡されるイベント情報を一挙紹介
- 全てのWidgetにbind関数を適用する
- bind関数の代わりにcommand optionを利用する
- まとめ
- 参考文献
執筆者 - おすすめの記事3選
そもそもTkinterで使われるbindとは?
Tkinterで使われるbindとは、イベントと関数の実行を紐付けるものを意味します。
別名でbind関数と呼ばれます。Tkinterを活用する上で非常に大切な関数になります。
そもそもTkinterで使われるイベントとは?
Tkinterで使われるイベントとは、
- Tkinterのアプリ内でボタンを選択する
- Tkinterのアプリ内で文字を入力する
- Tkinterのアプリ内でマウスを動かす
などの動作を意味します。
まとめると、Tkinterで活用されるbindとは、何か動作(ボタンを選択する、文字を入力するなど)が起こった場合に、関数の実行を手助けするものを意味します。
少しずつ歩みを進めていますが、謎は解けてきていますでしょうか?以下の「bindの仕組み」を確認しながら、さらに理解を深めましょう。
bindの仕組み
画像からわかる通り、bindの仕組みは、
- 「ユーザー」、「bind関数」、「関数」で構成される
- 始めにユーザーからイベント(画像の場合、ボタンを選択)を実行します
- イベント(画像の場合、ボタンを選択)が実行されると「bind関数」が働きます
- 「bind関数」によって、イベント(画像の場合、ボタンを選択)に紐づく関数を実行します
で成り立ちます。
以上のことから橋渡しするためにも、bind関数は必要になります。
tkinterで使われるbind関数の定義
bind関数は、
1# 第一引数 : sequence(イベント内容(ボタンを選択する、文字を入力するなど)を設定)
2# 第二引数 : func(第一引数のイベント内容(ボタンを選択する、文字を入力するなど)が実行された場合に、呼ばれる関数を設定)
3# 第三引数(任意) : add('+' or ''(デフォルト)を設定する。一つ前に宣言されるbind関数を実行するのか設定するために利用される。)
4# ''の場合、一つ前のbind関数で宣言された関数(第二引数)を実行しないで、今回bindする関数を実行する。
5# '+'の場合、一つ前のbind関数で宣言された関数(第二引数)を実行して、今回bindする関数を実行する。
6# 戻り値 : bind関数に紐づく独自ID
7.bind(sequence, func, add)
で定義されます。戻り値としてbind関数に紐づく独自IDが返されます。独自IDはbind関数を削除するために利用します。
またbind関数は全てのWidgetに対応可能です。
Widgetに関しては、【初学者必見!?】Tkinterで使われるlabelの活用方法を徹底解説の「Tkinterの構成要素」でまとめていますので、是非ご確認ください。
bind関数の各引数の詳細を説明する前に、まずは下準備を行いましょう。
下準備
下準備以降のbind関数の説明に関して、以下のコードを通して解説して参ります。コードを確認してみてください。できればコードに触れて、一緒にbind関数を実装しましょう。
1import tkinter as tk
2
3class Application(tk.Frame):
4 # 関数に紐づく、イベントの詳細情報を取得する関数
5 # event : イベント詳細情報
6 def getEventDetail(self, event):
7 print(event.keysym)
8
9 # 追加bind用の関数。実行される場合に、hello worldを出力する。
10 def getAddFunc(self, event):
11 print('hello world')
12
13 def __init__(self, master=None):
14 # Windowの初期設定を行う。
15 super().__init__(master)
16
17 # Windowの画面サイズを設定する。
18 # geometryについて : https://kuroro.blog/python/rozH3S2CYE0a0nB3s2QL/
19 self.master.geometry("300x200")
20
21 # Windowを親要素として、label Widgetを作成する。
22 # text : テキスト情報
23 # bg : 背景色を設定
24 # 色について : https://kuroro.blog/python/YcZ6Yh4PswqUzaQXwnG2/
25 # Labelについて : https://kuroro.blog/python/Pj4Z7JBNRvcHZvtFqiKD/
26 label = tk.Label(self.master, text="test", bg='blue')
27
28 # イベントと関数の実行を紐づける。
29 # 第一引数 : イベント内容。label Widgetがクリックされた場合
30 # 第二引数 : 第一引数が実行された場合に、呼び出す関数。self.getEventDetailとする。
31 # 戻り値 : bind関数に紐づく独自ID
32 label.bind("<ButtonPress>", self.getEventDetail)
33 # イベントと関数の実行を紐づける。
34 # 第一引数 : イベント内容。label Widgetがクリックされた場合
35 # 第二引数 : 第一引数が実行された場合に、呼び出す関数。self.getAddFuncとする。
36 # 第三引数 : ''か'+'を指定する。(デフォルト : '')
37 # ''の場合、一つ前のbind関数で宣言された関数を実行しないで、今回bindする関数を実行する。今回の場合、self.getEventDetailを実行しないで、self.getAddFuncを実行する。
38 # '+'の場合、一つ前のbind関数で宣言された関数を実行して、今回bindする関数を実行する。今回の場合、self.getEventDetailを実行して、self.getAddFuncを実行する。
39 # 戻り値 : bind関数に紐づく独自ID
40 label.bind("<ButtonPress>", self.getAddFunc, '+')
41
42 # Windowを親要素とした場合に、label Widgetをどのように配置するのか?
43 # packについて : https://kuroro.blog/python/UuvLfIBIEaw98BzBZ3FJ/
44 label.pack()
45
46
47# Tkinter初学者参考 : https://docs.python.org/ja/3/library/tkinter.html#a-simple-hello-world-program
48if __name__ == "__main__":
49 # Windowを生成する。
50 # Windowについて : https://kuroro.blog/python/116yLvTkzH2AUJj8FHLx/
51 root = tk.Tk()
52 app = Application(master=root)
53
54 # Windowをループさせて、継続的にWindow表示させる。
55 # mainloopについて : https://kuroro.blog/python/DmJdUb50oAhmBteRa4fi/
56 app.mainloop()
sequence
sequenceではイベント内容(ボタンを選択する、文字を入力するなど)を設定します。
sequenceの値は文字列で指定し、次のような形式で入力します。
<modifier-type-detail>
- modifier : イベントの条件を設定する。(例) Shiftキーを押しながらボタンを選択する, Controlキーを押しながらボタンを選択するなど。
- type : イベントの種類。(例) ボタンが押された, ボタンからマウスが離れたなど。
- detail : イベントの種類の詳細。(例) 特定のボタンが押された、特定のキーが押されたなど。
文字列の種類に関しては、以下の表にまとめましたので、是非ご確認ください。
type | 意味 | 利用可能なmodifier | 利用可能なdetail | 利用例(下準備に対応) |
---|---|---|---|---|
Button, ButtonPress | ボタンが押された | Shift, Control, Alt, Lock, Double, Triple, Button1 または B1, Button2 または B2, Button3 または B3, Button4 または B4, Button5 または B5 | -N(Nは数字)を付加することで特定のボタンを指定できる。 | label.bind("<ButtonPress>", self.getEventDetail) , label.bind("<Shift-Button-1>", self.getEventDetail) |
ButtonRelease | マウスがボタンから離れた | Shift, Control, Alt, Lock, Double, Triple, Button1 または B1, Button2 または B2, Button3 または B3, Button4 または B4, Button5 または B5 | -N(Nは数字)を付加することで特定のボタンを指定できる。 | label.bind("<ButtonRelease>", self.getEventDetail) |
Key, KeyPress | キーが押された | Shift, Control, Alt, Lock, Double, Triple, Button1 または B1, Button2 または B2, Button3 または B3, Button4 または B4, Button5 または B5 | -K(Kは文字)を付加することで特定のキーを指定できる。 | label.bind("<KeyPress>", self.getEventDetail) , label.bind("<Control-Key-a>", self.getEventDetail) |
KeyRelease | キーから離れた | Shift, Control, Alt, Lock, Double, Triple, Button1 または B1, Button2 または B2, Button3 または B3, Button4 または B4, Button5 または B5 | -K(Kは文字)を付加することで特定のキーを指定できる。 | label.bind("<KeyRelease>", self.getEventDetail) |
Motion | マウスの移動 | Shift, Control, Alt, Lock, Double, Triple, Button1 または B1, Button2 または B2, Button3 または B3, Button4 または B4, Button5 または B5 | x | label.bind("<Motion>", self.getEventDetail) |
Enter | マウスカーソルが画面内に入った | Shift, Control, Alt, Lock, Double, Triple, Button1 または B1, Button2 または B2, Button3 または B3, Button4 または B4, Button5 または B5 | x | label.bind("<Enter>", self.getEventDetail) |
Leave | マウスカーソルが画面から外れた | Shift, Control, Alt, Lock, Double, Triple, Button1 または B1, Button2 または B2, Button3 または B3, Button4 または B4, Button5 または B5 | x | label.bind("<Leave>", self.getEventDetail) |
※ type(イベント)の種類一覧を確認したい場合、以下のようにコードを記述してご確認ください。
1import tkinter
2# type(イベント)の種類一覧を表示
3print(tkinter.EventType.__members__)
以下print(tkinter.EventType.members)の出力結果です。
func
funcではイベント内容(ボタンを選択する、文字を入力するなど)が実行された場合に、呼ばれる関数を設定します。
funcの値は、次のように関数名を指定します。
1def 関数名(event):
2 # 処理
3 # ...
4 # ...
5
6label.bind("<modifier-type-detail>", 関数名)
add
addでは一つ前に宣言されるbind関数を実行するのか設定できます。
addの値として、'' or '+'を指定できます。(''はデフォルト)
''の場合、一つ前のbind関数で宣言された関数(以下のコードだと関数A)を実行しないで、今回bindする関数(以下のコードだと関数B)を実行します。
反対に'+'の場合、一つ前のbind関数で宣言された関数(以下のコードだと関数A)を実行して、今回bindする関数(以下のコードだと関数B)を実行します。
1def 関数A(event):
2 # 処理
3 # ...
4 # ...
5
6def 関数B(event):
7 # 処理
8 # ...
9 # ...
10
11label.bind("<modifier-type-detail>", 関数A)
12label.bind("<modifier-type-detail>", 関数B, '') or label.bind("<modifier-type-detail>", 関数B, '+')
bind関数を削除する
bind関数を削除するためには、unbind関数の利用が必要です。
unbind関数は、
1# 第一引数 : sequence(イベント内容(ボタンを選択する、文字を入力するなど)を設定)
2# 第二引数 : bind関数に紐づく独自ID
3# 戻り値 : なし
4.unbind(sequence, id)
で定義されます。戻り値はありません。
例えば以下のようなコードを作成して、
1import tkinter as tk
2
3class Application(tk.Frame):
4 # 関数に紐づく、イベントの詳細情報を取得する関数
5 # event : イベント詳細情報
6 def getEventDetail(self, event):
7 print(event.keysym)
8
9 def __init__(self, master=None):
10 # Windowの初期設定を行う。
11 super().__init__(master)
12
13 # Windowの画面サイズを設定する。
14 # geometryについて : https://kuroro.blog/python/rozH3S2CYE0a0nB3s2QL/
15 self.master.geometry("300x200")
16
17 # Windowを親要素として、label Widgetを作成する。
18 # text : テキスト情報
19 # bg : 背景色を設定
20 # 色について : https://kuroro.blog/python/YcZ6Yh4PswqUzaQXwnG2/
21 # Labelについて : https://kuroro.blog/python/Pj4Z7JBNRvcHZvtFqiKD/
22 label = tk.Label(self.master, text="test", bg='blue')
23
24 # イベントと関数の実行を紐づける。
25 # 第一引数 : イベント内容。label Widgetがクリックされた場合
26 # 第二引数 : 第一引数が実行された場合に、呼び出す関数。self.getEventDetailとする。
27 # 戻り値 : bind関数に紐づく独自ID
28 id = label.bind("<ButtonPress>", self.getEventDetail)
29
30 # 登録されたbind関数を削除する。
31 # 第一引数 : sequence(イベント内容(ボタンを選択する、文字を入力するなど)を設定)
32 # 第二引数 : bind関数に紐づく独自ID
33 # 戻り値 : なし
34 label.unbind("<ButtonPress>", id)
35
36 # Windowを親要素とした場合に、label Widgetをどのように配置するのか?
37 # packについて : https://kuroro.blog/python/UuvLfIBIEaw98BzBZ3FJ/
38 label.pack()
39
40# Tkinter初学者参考 : https://docs.python.org/ja/3/library/tkinter.html#a-simple-hello-world-program
41if __name__ == "__main__":
42 # Windowを生成する。
43 # Windowについて : https://kuroro.blog/python/116yLvTkzH2AUJj8FHLx/
44 root = tk.Tk()
45 app = Application(master=root)
46
47 # Windowをループさせて、継続的にWindow表示させる。
48 # mainloopについて : https://kuroro.blog/python/DmJdUb50oAhmBteRa4fi/
49 app.mainloop()
'test'ボタンを選択すると、self.getEventDetail関数が実行されない = unbind関数によってbind関数が削除されたようになります。
関数に渡されるイベント情報を一挙紹介
bind関数を用いてイベントから関数を実行すると、実行される関数の引数へイベント情報が付与されます。
1# 関数の場合
2def 関数名(event):
3 # イベント情報
4 print(event)
5 ...
6 ...
7
8# クラスメソッドの場合
9# クラスメソッドとは? : https://techacademy.jp/magazine/40330#:~:text=%E3%82%AF%E3%83%A9%E3%82%B9%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%20%E3%81%A8%E3%81%AF%E3%82%AF%E3%83%A9%E3%82%B9%E3%81%AB%E7%B4%90%E3%81%A5%E3%81%91%E3%82%89%E3%82%8C%E3%81%9F,%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%81%AB%E8%A8%98%E8%BF%B0%E3%81%97%E3%81%BE%E3%81%99%E3%80%82
10def 関数名(self, event):
11 # イベント情報
12 print(event)
13 ...
14 ...
実際にどのような内容が書き込まれているのか、イベント情報を一挙にご紹介いたします。
num
マウスボタンの番号を取得できます。
例えば下準備コードのprint(event.keysym)
箇所を、以下のように変更すると、
1print(event.num)
以下の画像のようにマウスボタンの番号を取得できます。
x, y
それぞれWidgetのx座標, y座標を取得できます。
例えば下準備コードのprint(event.keysym)
箇所を、以下のように変更すると、
1- print(event.keysym)
2+ print(event.x)
3+ print(event.y)
以下の画像のようにlabel Widgetのx座標, y座標を取得できます。
time
イベントの発生時刻をタイムスタンプ型で取得できます。
例えば下準備コードのprint(event.keysym)
箇所を、以下のように変更すると、
1print(event.time)
以下の画像のようにイベントの発生時刻を取得できます。
char
キーに対応する文字を取得できます。
例えば下準備コードのprint(event.keysym)
箇所を、以下のように変更すると、
1print(event.char)
キーに対応する文字を取得できます。
keysym
キーに対応する名前を取得できます。
widget
イベントを実行したWidgetの名前を取得できます。
例えば下準備コードのprint(event.keysym)
箇所を、以下のように変更すると、
1print(event.widget)
以下の画像のようにイベントを実行したlabel Widgetの名前を取得できます。
keysym_num, keycode
キーに対応する名前を数字で取得できます。
例えば下準備コードのprint(event.keysym)
箇所を、以下のように変更すると、
1print(event.keysym_num)
キーに対応する名前を数字で取得できます。
x_root, y_root
それぞれWindowのx座標, y座標を取得できます。
例えば下準備コードのprint(event.keysym)
箇所を、以下のように変更すると、
1- print(event.keysym)
2+ print(event.x_root)
3+ print(event.y_root)
以下の画像のようにWindowのx座標, y座標を取得できます。
type
イベントを発生した要因を取得できます。
例えば下準備コードのprint(event.keysym)
箇所を、以下のように変更すると、
1print(event.type)
以下の画像のようにイベントを発生した要因を取得できます。
全てのWidgetにbind関数を適用する
bind_all関数を利用すると、全てのWidgetに対して、bind関数を適用できます。
つまり一度bind_all関数を宣言すると、bind_all関数で定義するイベント内容が、Window(画面内)で実行される度に、関数の実行が行われます。
bind_all関数は、bind関数と同じく
1# 第一引数 : sequence(イベント内容(ボタンを選択する、文字を入力するなど)を設定)
2# 第二引数 : func(第一引数のイベント内容(ボタンを選択する、文字を入力するなど)が実行された場合に、呼ばれる関数を設定)
3# 第三引数(任意) : add('+' or ''(デフォルト)を設定する。一つ前に宣言されるbind関数を実行するのか設定するために利用される。)
4# ''の場合、一つ前のbind関数で宣言された関数(第二引数)を実行しないで、今回bindする関数を実行する。
5# '+'の場合、一つ前のbind関数で宣言された関数(第二引数)を実行して、今回bindする関数を実行する。
6# 戻り値 : bind_all関数に紐づく独自ID
7.bind_all(sequence, func, add)
で定義されます。戻り値として、bind_all関数に紐づく独自IDが返されます。独自IDはbind_all関数を削除するために利用します。
例えば下準備コードのlabel.bind("<ButtonPress>", self.getEventDetail)
箇所を、以下のように変更すると、
1label.bind_all("<ButtonPress>", self.getEventDetail)
Window(画面内)でlabel Widget以外を選択しても、関数が実行されるようになります。
bind関数の代わりにcommand optionを利用する
bind関数の代わりにcommand optionを利用しても、イベントと関数の実行を紐付けられます。
しかしcommand optionを利用できるWidgetは限られているため、
- command optionが利用できるか調べる
- command optionが使用できる場合、利用する
- command optionが活用できない場合、bind関数を利用する
と手順を踏んで、活用することをおすすめします。
例えば以下のようなコードを記述して、
1import tkinter as tk
2
3class Application(tk.Frame):
4 # hello worldを出力する関数
5 def getHelloWorld(self):
6 print('hello world')
7
8 def __init__(self, master=None):
9 # Windowの初期設定を行う。
10 super().__init__(master)
11
12 # Windowの画面サイズを設定する。
13 # geometryについて : https://kuroro.blog/python/rozH3S2CYE0a0nB3s2QL/
14 self.master.geometry("300x200")
15
16 # Windowを親要素として、button Widgetを作成する。
17 # command : ボタンをクリックした時に、実行する関数を設定。self.getHelloWorldとする。
18 # text : テキスト情報
19 # Buttonについて : https://kuroro.blog/python/oFju6EngDtcYtIiMIDf1/
20 button = tk.Button(self.master, command=self.getHelloWorld, text='test')
21
22 # Windowを親要素とした場合に、button Widgetをどのように配置するのか?
23 # packについて : https://kuroro.blog/python/UuvLfIBIEaw98BzBZ3FJ/
24 button.pack()
25
26# Tkinter初学者参考 : https://docs.python.org/ja/3/library/tkinter.html#a-simple-hello-world-program
27if __name__ == "__main__":
28 # Windowを生成する。
29 # Windowについて : https://kuroro.blog/python/116yLvTkzH2AUJj8FHLx/
30 root = tk.Tk()
31 app = Application(master=root)
32
33 # Windowをループさせて、継続的にWindow表示させる。
34 # mainloopについて : https://kuroro.blog/python/DmJdUb50oAhmBteRa4fi/
35 app.mainloop()
'test'ボタンを選択するとself.getHelloWorld
関数を実行して、以下の画像のように'hello world'を表示できます。
またcommand optionが利用できるか調べる場合、以下のコードを実行して
1# button Widgetの場合 : widget = tk.Button()
2widget = tk.{Widget名}()
3print(widget.keys())
option対応しているのか、ご確認ください。
buttonに関しては、Tkinterで使われるbuttonとは?コード例を交えて実践的な活用方法を解説でまとめていますので、是非ご確認ください。
まとめ
- Tkinterで使われるbindとは、イベントと関数の実行を紐付けるものを意味します。
- 別名でbind関数と呼ばれます。
- bind関数は、
.bind(sequence, func, add)
で定義されます。