TkinterのGUIアプリを作成する時に出会った問題
bindメソッドが呼び出したコールバック関数の処理結果をどうやって保存できるか
(=マウスなどのユーザー操作がイベントとしてトリガーし、コールバック関数を呼び出す)
手順として下記の通り:
- インスタンス変数の形で処理結果を保存するクラスを定義
- 手順1で定義したクラスに基づいて、オブジェクトを1個作成しておく
- bindメソッドを呼び出す時に手順2のクラスオブジェクトをコールバック関数に渡す
- コールバック関数内で渡された引数のクラスオブジェクトに対して処理結果を設定
下記のサンプルコードではTkinter GUIウィンドウが表示された後、
bindメソッドにより、左マウスボタンがクリックされるたびにb1Pressedというコールバック関数が呼びされる
ラムダ関数の形でb1Pressedに渡される引数としてイベント(e)自体以外、obj1というクラスオブジェクトも指定する
b1Pressedは呼び出されるたびにobj1.var_hogeに1を加算し、処理結果はobj1.var_hogeに保存する
guiTest.py
import tkinter as tk
from tkinter import ttk
import PIL
from PIL import Image,ImageTk
root = tk.Tk()
root.title('hoge')
root.minsize(796,816)
#画像の読み込み
img = PIL.Image.open(r"C:\Users\User\Desktop\experiment\a.png")
im = PIL.ImageTk.PhotoImage(img)
#マウスクリックイベントハンドラー
def b1Pressed(e, obj1):
print("b1Pressedが呼び出された!")
obj1.var_hoge += 1
print("var_hogeは"+ str(obj1.var_hoge))
#コールバック関数で行った変数の処理結果を格納する用のクラス
class storeVar():
def __init__(self):
self.var_hoge = 0
#Canvas設定
cvs = tk.Canvas(bg="black", width=796, height=816)
cvs.place(x=0, y=0)
cvs.create_image(0,0,image=im, anchor=tk.NW)
#クラスオブジェクトを準備
obj1 = storeVar()
#マウスボタンが押された時にイベントハンドラーを呼び出す
cvs.bind("<ButtonPress-1>", lambda event, arg=obj1:b1Pressed(event, arg))
root.mainloop()
処理結果は以下の通り(4回左マウスボタンをクリックした結果)
guiTest.pyの実行結果
b1Pressedが呼び出された!
var_hogeは1!
b1Pressedが呼び出された!
var_hogeは2!
b1Pressedが呼び出された!
var_hogeは3!
b1Pressedが呼び出された!
var_hogeは4!