Search code examples
pythontkinterenumerate

Python Tkinter title change from list


I've tried to simplify the issue with my program through the code below. I can get it to work but am curious as to why it won't work using the method below.

The print values show the first index, yet the function calls the last index.

list1 = ["Title_0", "Title_1"]

for i, string in enumerate(list1):
if i == 0:
    print str(i) + ",  " + string # Prints: 0, Title_0
    btn_monty = Button(the_window, text='Monty Python', command = lambda:the_window.title(string))
    #### This also doesn't work ####
    #  btn_monty = Button(the_window, text='Monty Python', command = lambda:the_window.title(list1[i]))

Solution

  • The issue is that the string within the lambda is closed on the variable string, not the value of string . That means that the value for variable string is not evaluated until the button is actually called, and when it gets called it uses the latest value of string which would be same for both buttons.

    You can instead try using default arguments to pass string . Example -

    list1 = ["Title_0", "Title_1"]
    
    for i, strng in enumerate(list1):
        print str(i) + ",  " + strng # Prints: 0, Title_0
        btn_monty = Button(the_window, text='Monty Python', command = lambda new_title=strng:the_window.title(new_title))
    

    I also changed the variable to strng so that it does not conflict with the string module (would be good to avoid any kind of issues in future if you decide to import that module). Also, you should make sure you place the buttons using grid or pack, etc.