1

I am using a lambda in a tkinter callback. It produces the correct result but throws an error. An error I do not understand and have not been able to isolate and eliminate. The goal is to get two user inputs via Entry widgets, the second one has a trace on it. The trace takes the two Entry widgets and calculates the mark up (100*((var1-var2)/var2)) returning that value. The Form shows the mark up correctly but I also get an error and I want to eliminate that error. The error indicates it is is expecting a DoubleVar and is getting ''. All three variables are DoubleVar (var1, var2, mu). I am down to it having something to do with self but I do not understand enough to be able to get to the finish line. Any suggestions or pointers would be greatly appreciated.

from tkinter import *

def var2_callback(var1, var2, mu):
    #print('var1: %d' % var1.get())
    #print('var2: %d' % var2.get())
    #print('mu: %d' % mu.get())
    markup = var1.get() * var2.get()
    mu.set(markup)
    #print('times: %d' % mu.get())
    return()


def do_something():
    mu = DoubleVar(value=0)
    root.grid_columnconfigure((0,1,2,3,4,5), weight=1)
    root.grid_rowconfigure((0,1,2,3,4,5,6,7,8,9,10), weight=1)
    cf = Frame(root)
    cf.grid(row=0, column=2)

    lbl1 = Label(cf, textvariable=mu)
    lbl1.grid(row=0, column=2)

    var1 = DoubleVar(value=0)
    e1 = Entry(cf, textvariable=var1)
    e1.grid(row=2, column=2)

    var2 = DoubleVar(value=0)
    var2.trace('w',lambda name, index, mode, var2=var2: var2_callback(var1,var2,mu))
    e2 = Entry(cf, textvariable=var2)
    e2.grid(row=3, column=2)


root = Tk()
root.geometry("1000x600+0+0")
do_something()
root.mainloop()

The error I get is:

Exception in Tkinter callback
Traceback (most recent call last):
  File "/usr/lib/python3.6/tkinter/__init__.py", line 1705, in __call__
    return self.func(*args)
  File "for_entry.py", line 28, in <lambda>
var2.trace('w',lambda name, index, mode, mu=mu: var2_callback(var1,var2,mu))
  File "for_entry.py", line 7, in var2_callback
markup = var1.get() * var2.get()
  File "/usr/lib/python3.6/tkinter/__init__.py", line 529, in get
    return self._tk.getdouble(self._tk.globalgetvar(self._name)_tkinter.TclError: expected floating-point number but got ""

I am wanting to eliminate the error. I know if I comment out the mu.set line I can eliminate the error (and the mu calc...). I do not understand what rule I am breaking in passing back the mu result.

*** UPDATE

The problem is that some how the trace callback is called twice. The first time var2 is empty even with var2 being set to 0. The second time through it works. Trying to figure out why var2 is empty on the first time through. I have verified this by adding print statements at the beginning of the callback function. I have tried to avoid the problem by setting var2 (var2.set(0)) at the beginning of the callback function - that avoids the problem but obviously prevents the function from preforming the calculation. I can not figure out how to use an 'if' statement to test var2. 'if var2.get() == None: or if var2.get() != None or if var2.get() > 0' all result in the same error that var2 is '' and was expected to be a DoubleVar. Is this problem caused by using a function and not a Class?

3
  • 2
    It is because one of the entries has empty content. Use try/except to cater the error. Commented Jun 8, 2020 at 5:40
  • 1
    The indentation in your code example is broken and needs fixing. Commented Jun 8, 2020 at 14:52
  • acw1668 - you are correct that on the first 'pass through' the callback one of the variables is empty. I believe it to be var2. You suggest using try/except to cater the error. Could you give me a little more info? It is not clear to me what I am trying to cater as I do not understand why any of the three variables are empty in the first place. Any guidance is appreciated. Commented Jun 11, 2020 at 3:50

1 Answer 1

0

Thank you acw1668 for pointing me in the direction of being able to mask the issue using try/except. That allowed me to hide the error on the trace. The trace was firing on the decimal (as in .5) and that created an illegal calculation (. times something makes no sense). That in turn led me to using a bind (bind on the Tab key, UP arrow, down arrow) on the Event not the variable and that worked out much better.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.