tkinterで複数個のボタンの配置
tkinter
を使っていて、ボタンなど同じ物を複数個作成する際、1 つずつ作成していると面倒なので、loop
を使って以下のような方法をとると思います。
import tkinter as tk
root = tk.Tk()
buttons = []
# 5つのボタンを追加
for i in range(0,5):
buttons.append(tk.Button(root, text=f"{i}番目のボタン"))
buttons[i].pack()
root.mainloop()
bind処理の追加
ここに bind
で右クリック処理を付けます。
import tkinter as tk
+ from tkinter import messagebox
+ # クリック関数
+ def click(event):
+ messagebox.showinfo("情報", "クリックしました")
+ return
root = tk.Tk()
buttons = []
# 5つのボタンを追加
for i in range(0, 5):
buttons.append(tk.Button(root, text=f"{i}番目のボタン"))
buttons[i].pack()
+ # bind 処理追加 右クリックに処理を付ける
+ buttons[i].bind("<Button-3>", click)
root.mainloop()
ただ、これでは何番目のボタンをクリックしたかわかりません。
lambda
関数を使えば関数に引数を渡せるため上手くいきそうです。
import tkinter as tk
from tkinter import messagebox
# クリック関数
- def click(event):
- messagebox.showinfo("情報", "クリックしました")
+ def click(event, i):
+ messagebox.showinfo("情報", f"{i}をクリックしました")
return
root = tk.Tk()
buttons = []
# 5つのボタンを追加
for i in range(0, 5):
buttons.append(tk.Button(root, text=f"{i}番目のボタン"))
buttons[i].pack()
# bind 処理追加 右クリックに処理を付ける
+ # lambda 関数で引数を渡す
- buttons[i].bind("<Button-3>", click)
+ buttons[i].bind("<Button-3>", lambda event: click(event, i))
root.mainloop()
実行すると、確かに「4 をクリックしました」と表示されるので、値が送られています。ただ、どこを押しても「4 をクリックしました」となってしまいます。
これは、ボタンをクリックした際に i
の値を参照するためで、(クリックするときは 5 つのボタンが作成された後であるため)i
の値 4
がすべてのボタンで表示されてしまっています。
解消方法
この現象を回避するためにヘルパー関数を間に挟むことで解消できます。
import tkinter as tk
from tkinter import messagebox
# クリック関数
def click(event, i):
messagebox.showinfo("情報", f"{i}をクリックしました")
return
+ # ヘルパー関数
+ def helper_lambda(i):
+ return lambda event: click(event, i)
root = tk.Tk()
buttons = []
# 5つのボタンを追加
for i in range(0, 5):
buttons.append(tk.Button(root, text=f"{i}番目のボタン"))
buttons[i].pack()
# bind 処理追加 右クリックに処理を付ける
- # lambda 関数で引数を渡す
+ # ヘルパー関数を通してクリック関数を呼び出す
- buttons[i].bind("<Button-3>", lambda event: click(event, i))
+ buttons[i].bind("<Button-3>", helper_lambda(i))
root.mainloop()
これで、押された番号の i
を参照することができました。
今回の最終コード
import tkinter as tk
from tkinter import messagebox
# クリック関数
def click(event, i):
messagebox.showinfo("情報", f"{i}をクリックしました")
return
# ヘルパー関数
def helper_lambda(i):
return lambda event: click(event, i)
root = tk.Tk()
buttons = []
# 5つのボタンを追加
for i in range(0, 5):
buttons.append(tk.Button(root, text=f"{i}番目のボタン"))
buttons[i].pack()
# bind 処理追加 右クリックに処理を付ける
# ヘルパー関数を通してクリック関数を呼び出す
buttons[i].bind("<Button-3>", helper_lambda(i))
root.mainloop()