Reputation: 23
first post here.
I am trying to make a list of movies. The movies will be shown in a list on Tkinter. The plan was when you click an update button the program will update the Label next to it. The problem is no matter which button you click it always updates the last label. I think this is because
lambda: self.update_rating(x)
is evaluated at run time, and so is x. I want x to be what it was on that specific loop, not what it was outside of scope when the button was clicked.
I am new to python so any help is appreciated
code:
from Tkinter import *
class Application(Frame):
def __init__(self, master):
Frame.__init__(self, master)
self.grid()
self.create_widgets()
def create_widgets(self):
self.movies = list()
for x in range(0, 10):
movie = list()
rating = Label(self, text = "Rating: NA")
rating.grid(row = x, column = 0, columnspan = 1, sticky = W)
movie.append(rating)
update = Button(self, text = "update", command = lambda: self.update_rating(x))
update.grid(row = x, column = 1, columnspan = 1, sticky = W)
movie.append(update)
self.movies.append(movie)
def update_rating(self, num):
self.movies[num][0]["text"] = "rating updated"
root = Tk()
root.title("Movie Sorter")
root.geometry("640x480")
app = Application(root)
root.mainloop()
Upvotes: 2
Views: 102
Reputation: 309969
Use this instead:
lambda x=x: self.update_rating(x)
Demonstration:
>>> x = 1
>>> a = lambda x=x:x
>>> a()
1
>>> x = 2
>>> a()
1
The idea here is that default arguments are evaluated when a function is defined as opposed to creating a closure which evaluates picks up the variables from the enclosing scope when the function is called.
Upvotes: 2