1

I'm trying to write a GUI for my code. My plan is to use tkinter's StringVar, DoubleVar, etc. to monitor my input in real time. So I found out the DoubleVar.trace('w', callback) function. However, every time I make the change I get an exception:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\Anaconda2\lib\lib-tk\Tkinter.py", line 1542, in __call__
    return self.func(*args)
TypeError: 'NoneType' object is not callable

I have no idea what's going wrong. I'm using python 2.7 My code is as follows:

from Tkinter import *
class test(Frame):
    def __init__(self,master):
        Frame.__init__(self,master=None) 
        self.main_frame = Frame(master);
        self.main_frame.pack() 
        self.testvar = DoubleVar()
        self.slider_testvar = Scale(self.main_frame,variable = self.testvar,from_ = 0.2, to = 900, resolution = 0.1, orient=HORIZONTAL,length = 300)
        self.slider_testvar.grid(row = 0, column = 0, columnspan = 5)       
        self.testvar.trace('w',self.testfun())    
    def testfun(self):
        print(self.testvar.get())

root = Tk()
root.geometry("1024x768")
app = test(master = root) 
root.mainloop() 
Christian Dean
  • 22,138
  • 7
  • 54
  • 87
Charlieboy
  • 13
  • 3
  • 1
    I cannot reproduce using Python 2.7 on Ubuntu 16.04. Everything works for me. Are you sure this is all of your code? – Christian Dean Jun 07 '17 at 20:00
  • Change your trace to `self.testvar.trace('w', self.testfun)` to prevent execution on declarition and definition of your callback to `def testfun(self, *args):` to supply more than one argument. Links: [similar problem](https://stackoverflow.com/questions/5767228/why-is-button-parameter-command-executed-when-declared), [trace callback arguments](https://stackoverflow.com/questions/29690463/what-are-the-arguments-to-tkinter-variable-trace-method-callbacks). – CommonSense Jun 07 '17 at 20:03
  • 1
    @CommonSense Can you post you answer in the comment above as an Answer? So it can be 'accepted'? – Terry Jan Reedy Jun 07 '17 at 20:28
  • @CommonSense, thank you very much, you saved my day. – Charlieboy Jun 08 '17 at 08:54

1 Answers1

0

Consider this line of code:

self.testvar.trace('w',self.testfun())  

This is exactly the same as this:

result = self.testfun()
self.testvar.trace('w', result)

Since the function returns None, the trace is going to try to call None, and thus you get 'NoneType' object is not callable

The trace method requires a callable. That is, a reference to a function. You need to change that line to be the following (notice the missing () at the end):

self.testvar.trace('w',self.testfun) 

Also, you need to modify testfun to take arguments that are automatically passed by the tracing mechanism. For more information see What are the arguments to Tkinter variable trace method callbacks?

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • Thank you very much – Charlieboy Jun 08 '17 at 08:55
  • @Bryan Oakley You are the master of patience. I feel like on third of tkinter questions are exactly this problem – Jannick Jun 08 '17 at 11:57
  • @Jannick: there are definitely a _lot_ of questions related to calling a function rather than providing a reference. The problem is that this is a somewhat hard concept for beginner programmers to wrap their head around. – Bryan Oakley Jun 08 '17 at 12:04