jordanpastry
jordanpastry

Reputation: 55

'str' object has no attribute 'get' in Tkinter callback

I'm trying to trace an OptionMenu widget's choice so that different choices run a different function. However, I keep running into the error below:

Exception in Tkinter callback
Traceback (most recent call last):
  File "-", line 1705, in __call__
    return self.func(*args)
  File "-", line 149, in callback
    self.bookingCanvas(optVar)
  File "-", line 152, in bookingCanvas
    perfDate = optVar.get()
AttributeError: 'str' object has no attribute 'get'

Here is the relevant code:

    optVar = StringVar(self.root)
    optVar.trace('r', callback=self.callback)
    optVar.set("06/10/20") # default value
    optMenu_Label = Label(self.root, text='Select a performance date:',bg='gray15', fg='yellow', relief=GROOVE)
    optMenu_Label.pack(side=TOP, anchor=NW, padx=15, pady=15)

    optMenu = OptionMenu(self.root, optVar, '04/10/20','5/10/20','6/10/20')
    optMenu.pack(side=TOP,anchor=NW, padx=35, pady=3)

The callback of the .trace() above:

    def callback(self, optVar, *args):
    print("SOMETHING HAS CHANGED")
    self.bookingCanvas(optVar)

The error area (I assume):

    def bookingCanvas(self, optVar):
        perfDate = optVar.get()
        print("This is a Date >>>",perfDate)
        print("did we get here?")

Upvotes: 0

Views: 1420

Answers (1)

Bryan Oakley
Bryan Oakley

Reputation: 386285

The callback from a trace is given the name of the variable, not a reference to the variable object. The name is a string, which is why you're getting the error AttributeError: 'str' object has no attribute 'get'.

With the name, you can use the common widget method getvar to get the value stored in the variable.

In your definition of callback you can get the value and pass it to your function like so: (assuming for this example that you have a global variable named 'root` which represents the root widget)

def callback(self, optVar_name, *args):
    print("SOMETHING HAS CHANGED")
    value = root.getvar(optVar_name)
    self.bookingCanvas(value)

With that, you can remove the call to get in bookingCanvas:

def bookingCanvas(self, perfDate):
    print("This is a Date >>>",perfDate)
    print("did we get here?")

Upvotes: 2

Related Questions