0

My aim is to update the same Label object every time the drop-down list selection changes. From what I know, because of closure, the outer environment object, lblResult must be available to the event handler function locationChanged(). But in the handler, lblResult is always None. I tried passing the lblResult object to the handler, declaring lblResult in event handler global, but none worked. If anyone can explain why it's so, how can I fix it, it will be a great help. Thanks.

   from tkinter import Label, OptionMenu, StringVar, Tk
    root = Tk()
    
    
    def locationChanged(x):
        lblResult.config(text=x)  # lblResult is None always
        #lblResult = Label(root, text=x).pack() # this works but I want the same Label to be updated
    
    locations=["Select a City...", "Amsterdam,NL", "NewYork,NY,US", "Sydney,NSW,AU", "Toronto,ON,CA"]
    selectedLocation = StringVar()
    ddlLocation = OptionMenu(root, selectedLocation, *locations, command=lambda x: locationChanged(x)).pack()
    lblResult = Label(root, text="").pack()
    
    root.mainloop()
Libni
  • 28
  • 5
  • First of all you never call `lblResult.pack()`. Also you shouldn't create a widget and call `.pack` on the same line. It can result in [this](https://stackoverflow.com/questions/1101750/tkinter-attributeerror-nonetype-object-has-no-attribute-attribute-name) problem – TheLizzard Jun 09 '21 at 15:46
  • The code you posted should never have `lblResult` being `None`. – Bryan Oakley Jun 09 '21 at 15:59
  • @BryanOakley The initial code that I posted missed the .pack() in the label widget creation line. Now I have added that. sorry for the confusion. Thanks for the comment. – Libni Jun 09 '21 at 16:23

1 Answers1

0

Try this:

import tkinter as tk

def location_changed(x):
    # Show the label
    lbl_result.pack()
    # Update the widget's text
    lbl_result.config(text=x)

root = tk.Tk()

locations = ("Select a City...", "Amsterdam,NL", "NewYork,NY,US", "Sydney,NSW,AU", "Toronto,ON,CA")

selected_location = tk.StringVar()
ddl_location = tk.OptionMenu(root, selected_location, *locations, command=location_changed)
ddl_location.pack()

lbl_result = tk.Label(root, text="")

root.mainloop()

You need to call lblResult.pack() inside the function. Also please make sure you don't call .pack() on the same line that you create your widgets or you might run into this problem.

TheLizzard
  • 7,248
  • 2
  • 11
  • 31
  • Thanks for the answer. I completely missed that I am storing the return value of pack() in lblResult. Also splitting the object creation line, into two like the following also fixes it. Thanks again. lblResult = Label(root, text="") lblResult.pack() – Libni Jun 09 '21 at 16:14