Options such as Button widget in Tkinter: I will show you how to pass arguments to communad.
import tkinter as tk
import tkinter.ttk as ttk
class Application(ttk.Frame):
def __init__(self, master=None):
super().__init__(master)
self.master = master
self.pack()
self.master.title("Title")
self.master.geometry("400x300")
self.create_widgets()
def create_widgets(self):
for i in range(1, 11):
ttk.Button(self, text=f"button{i}", command=self.show_message(i)).pack()
def show_message(self, index):
def inner():
print(f"button{index}Was clicked")
return inner
def main():
root = tk.Tk()
app = Application(master=root)
app.mainloop()
if __name__ == "__main__":
main()
When I try to write it normally, I tend to write it as follows:
import tkinter as tk
import tkinter.ttk as ttk
class Application(ttk.Frame):
def __init__(self, master=None):
super().__init__(master)
self.master = master
self.pack()
self.master.title("Title")
self.master.geometry("400x300")
self.create_widgets()
def create_widgets(self):
for i in range(1, 11):
ttk.Button(self, text=f"button{i}", command=self.show_message(i)).pack()
def show_message(self, index):
print(f"button{index}Was clicked")
def main():
root = tk.Tk()
app = Application(master=root)
app.mainloop()
if __name__ == "__main__":
main()
Unfortunately, this does not work as expected.
As you can see by moving it, self.show_message (i)
is executed when the button is generated, and all buttons {index} are clicked
are printed. And when the important button is clicked, no action is taken. This is related to the behavior of the command option as follows.
-** When widget is generated : self.show_message (i)
is executed
- When the button is clicked **: self.show_message (i) ()
is executed
Due to the troublesome specifications described above, some ingenuity is required when defining the callback function. Do not execute the necessary part of the code (in this case, print (f" button {index} was clicked ")
with self.show_message (i)
, and self You need to run it with .show_message (i) ()
.
To do this, use the ** Inner Function **. It is easy to understand if you think that it is as follows.
def show_message(index):
def inner():
print(f"button{index}Was clicked")
return inner
command = show_message(1)
command()
The inner function (internal function) is defined in the show_message function, and it is returned. In other words, the command
on the second line from the bottom contains the inner function. However, since the contents of the inner function have not been executed, it will not be printed. And on the last line, we are executing the inner function.
In other words, show_message (1)
does nothing in appearance, but show_message (1) ()
allows you to execute the desired part.
--python tkinter How to determine which button was pressed --memorpy http://memopy.hatenadiary.jp/entry/2017/06/11/220452 --When passing arguments with Tkinter's command option, it works as expected to define nesting in the function https://qiita.com/yukid/items/a0140b5c1a3e28f636f0
Recommended Posts