Tkinter: イベントを検出する(クリック・キー入力・マウス移動)

PythonのTkinterでイベント(クリック・キー入力・マウス移動) を検出する方法を紹介します。

イベント検出のコードを記述するにあたってポイントとなるのは 「bind()メソッド」、「bind_all()メソッド」、「commandオプション」です。
この3つの違いと使用方法がわかればイベント検出は難しくありません。

クリックイベントを検出

Tkinterでクリックイベントを検出する方法は2つあります。

ウィジェットのcommandオプションを使用する方法と、 ウィジェットのbind()メソッドを使用する方法です。 それぞれの方法について説明します。

commandオプションで検出

ウィジェットのcommandオプションをする場合のコードを紹介します。 次のコードはボタンがクリックされた時に、 btn_clicked()関数を実行します。

import tkinter as tk

def btn_clicked():
	print("Button Clicked")

# ウィンドウ作成
root = tk.Tk()

# ボタンの作成と配置
button1 = tk.Button(root, text="Button", command=btn_clicked)
button1.place(x=10, y=20, width=100, height=50)

# メインループ
root.mainloop()

ボタン作成時にcommandオプションを使用します。

「command=btn_clicked」 の部分でcomanndオプションの引数に実行したいイベントハンドラを指定しています。
これだけでクリックイベントを検出できます。

commandオプションを使用すると、 このようにシンプルにクリックイベントを検出できるのがメリットです。

一方デメリットとしては、イベントハンドラに引数を渡すことができないことや、 commandオプションを利用できるウィジェットが限られていることです。 (ButtonウィジェットやScaleウィジェットなど)

ウィジェットがcommandオプションを使用できるか確認したい場合は、 次の記事を参考にしてください。
参考記事:Tkinter ウィジェットのオプションを調べる方法

イベントハンドラに引数を渡す場合は、 次で紹介するbind()メソッドを使用します。

bind()メソッドで検出

bind()メソッドでクリックイベントを検出する方法を紹介します。

次のコードはボタンがクリックされた時に、 btn_clicked()関数を実行し、 クリックされたボタンのテキスト内容を表示します。

import tkinter as tk

def btn_clicked(e):
	print(e.widget["text"])

# ウィンドウ作成
root = tk.Tk()

# ボタンの作成と配置
button1 = tk.Button(root, text="Button",)
button1.place(x=10, y=20, width=100, height=50)
button1.bind("<Button-1>", btn_clicked)

# メインループ
root.mainloop()

bind()メソッドの書式は次の通りです。

書式
biind(イベントの種類, イベントハンドラ)

第1引数にはイベントの種類を指定します。
マウスクリックの場合、次のようなイベントの種類があります。

イベントの種類イベント内容
<Button-1>左ボタンを押したとき
<Button-2>真ん中ボタンを押したとき
<Button-3>右ボタンを押したとき
<ButtonRelease-1>左ボタンを離したとき
<ButtonRelease-2>真ん中ボタンを離したとき
<ButtonRelease-3>右ボタンを離したとき

第2引数にはイベントハンドラを指定します。 今回はイベントハンドラとして「btn_clicied()」を指定しています。

btn_clicked()関数には、 tkinter.Eventのインスタンスが引数として渡されるため、 それを受け取るために「btn_clicked(e)」と記述しています。

tkinter.Eventのインスタンスには次のような複数のプロパティがあります。

プロパティ概要
widgetウィジェット情報
xウィジェットのX座標
yウィジェットのY座標
numマウスボタンの番号

「e.widget["text"]」でウィジェットのtextプロパティの内容が取得できます。

キー入力を検出

キー入力を検出する場合は、 対象となるウィジェットのbind()メソッドを使います。

次のサンプルコードは、 テキストボックスでキー入力を検出した時に、 キーコードをprint()関数で表示します。

import tkinter as tk

def key_handler(e):

	print(e.keycode)

# ウィンドウ作成
root = tk.Tk()

# ウィンドウサイズ
root.geometry("300x200")

# テキストボックスの作成と配置
txt = tk.Entry(root)
txt.place(x=20, y=20, width=150, height=30)
txt.bind("<KeyPress>", key_handler)

# メインループ
root.mainloop()

bind()メソッドの書式を再度記述しておきます。

書式
biind(イベントの種類, イベントハンドラ)

第1引数にはイベントの種類を指定します。
キー入力の場合、次のようなイベントの種類があります。

イベントの種類イベント内容
<Key>キーを押したとき
<KeyPress>キーを押したとき
<KeyReLease>キーを離したとき

第2引数にはイベントハンドラを指定します。 今回はイベントハンドラとして「key_handler()」を指定しています。

key_handler()には、 tkinter.Eventのインスタンスが引数として渡されるため、 それを受け取るために「key_handler(e)」と記述しています。

キーコードを取得する場合は「e.keycode」と記述し、 keycodeプロパティを参照します。

テキストボックス以外のキー入力を検出する方法

上のサンプルコードはテキストボックスであるEntryウィジェットのbind()メソッドを 使用しているため、Entryウィジェット以外のキー入力は検出しません。

フォームに対してキー入力を検出する場合は bind_all()メソッドを使用するか、 メインウィンドウのbind()メソッドを使用します。

bind_all()を使う場合

txt.bind_all("<KeyPress>", key_handler)

メインウィンドウのbind()メソッドを使う

root.bind("<KeyPress>", key_handler)

マウスの移動を検出

マウスの移動を検出する場合は、 <Motion>イベントを使用します。

次のサンプルプログラムは、 フォーム上でマウスカーソルが動いたときに、 マウスのx, y座標をラベルに表示します。

import tkinter as tk

def mouse_move(e):

	lbl["text"] = str(e.x) + ", " + str(e.y)

# ウィンドウ作成
root = tk.Tk()

# ウィンドウサイズ
root.geometry("300x200")

# ラベルの作成と配置
lbl = tk.Label(root, text="", 
				borderwidth=2, relief="ridge")
lbl.place(x=20, y=20, width=260, height=30)

root.bind("<Motion>", mouse_move)

# メインループ
root.mainloop()

コード解説

root.bind("<Motion>", mouse_move)
イベントの種類イベント内容
<Motion>マウスが移動したとき

メインウィンドウのbind()メソッドを使用し、 第1引数のイベントに「"<Motion>"」、 第2引数のイベントハンドラに「mouse_move」を指定しています。

def mouse_move(e):

	lbl["text"] = str(e.x) + ", " + str(e.y)

「e.x」でマウスのx座標、「e.y」でy座標を取得できます。