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