Search code examples
pythontkinteroptionmenu

How to change the value of an option menu after user clicks?


I'm playing around with option menu. I have a list of countries called options. The option menu is set to the first index of options. How can I update the value if a user clicks on a different country? Basically the function doesn't work even though I click on the 2nd (options[1]) country in the option menu.

def first_country():
    from_country = start_clicked.get()
    if from_country == options[1]:
        my_pic = Image.open("usa_flag.png")
        resized = my_pic.resize((200, 100), Image.ANTIALIAS)
        new_pic = ImageTk.PhotoImage(resized)
        flag_label = Label(root, image=new_pic)
        flag_label = Label(root, text="function works")
        flag_label.grid(row=3, column=0)

start_clicked = StringVar()
start_clicked.set(options[0])
dropdown = OptionMenu(root, start_clicked, *options, command=first_country())  

Solution

  • command=first_country() should be command=first_country instead. The former one will execute the function immediately and assign None (result of the function) to command option.

    Also the callback for command option of OptionMenu expects an argument which is the selected item:

    def first_country(from_country):
        if from_country == options[1]:
            my_pic = Image.open("usa_flag.png")
            resized = my_pic.resize((200, 100), Image.ANTIALIAS)
            new_pic = ImageTk.PhotoImage(resized)
            # better create the label once and update its image here
            flag_label.config(image=new_pic)
            flag_label.photo = new_pic # save a reference of the image
    
    ...
    dropdown = OptionMenu(root, start_clicked, *options, command=first_country)
    ...
    # create the label for the flag image
    flag_label = Label(root)
    flag_label.grid(row=3, column=0)
    ...
    

    Note that I have created the label for the flag image once and update its image inside the function instead. Also you need to save the reference of the image if it is created inside a function, otherwise it will be garbage collected.