I'm trying to write a function to open a recent file when it's selected from a submenu, but when I loop through the recent files the last file is the only one that is recognized.
Here's a sample bit of code to illustrate the issue:
from Tkinter import *
class App(Frame):
def __init__(self, root):
Frame.__init__(self, root)
menubar = Menu(self, tearoff=0)
fileMenu = Menu(self, tearoff=0)
recentMenu = Menu(self, tearoff=0)
menubar.add_cascade(label="File", menu=fileMenu)
fileMenu.add_cascade(label="Open Recent", menu=recentMenu)
for name in ('file1.txt', 'file2.txt', 'file3.txt'):
recentMenu.add_command(label=name, command=lambda: self.load_file(name))
root.configure(menu=menubar)
root.geometry("200x200")
def load_file(self, f):
print f
if __name__ == "__main__":
root = Tk()
App(root).pack(fill="both", expand=True)
root.mainloop()
When I click on file2.txt for example, the program outputs file3.txt instead. I'm sure I'm missing something trivial, but I can't figure out what that is.
the following works:
...
for name in ('file1.txt', 'file2.txt', 'file3.txt'):
recentMenu.add_command(label=name, command=self.load_file(name))
...
def load_file(self, f):
def fun():
print f
return fun
In your version, at the moment, when you call the callback function, name
refers to the instance file3.txt
. In my version, the instances file1.txt
, file2,txt
, and so on, are captured inside closures (not strictly a closure, but very similar).
See closures in SO.