Reputation: 25
I am using Tkinter to move a circle in a canvas a certain amount every second and I have come across the TypeError: 'NoneType' object is not callable
error in Python. I believe the error is in this block of code:
def move(new_x0, new_y0, new_x1, new_y1):
new_x0 = new_x0 + speed
new_y0 = new_y0 + speed
new_x1 = new_x1 + speed
new_y1 = new_y1 + speed
game.canvas.delete("all")
obj = game.canvas.create_oval(new_x0, new_y0, new_x1, new_y1, fill = color)
game.canvas.pack()
t = threading.Timer(1.0, move(x0, y0, x1, y1))
t.start()
I expected the circle on the canvas to move locations once after 1 second but it just displays the NoneType error.
Edit: Sorry, I forgot to show the error. Here it is.
Exception in thread Thread-1:
Traceback (most recent call last):
File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64\lib\threading.py", line 917, in _bootstrap_inner
self.run()
File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64\lib\threading.py", line 1158, in run
self.function(*self.args, **self.kwargs)
TypeError: 'NoneType' object is not callable
Edit: I solved the NoneType error by doing return obj and then I got int object is not callable, which I solved by doing what ShadowRanger suggested, so my code works now.
Upvotes: 0
Views: 6892
Reputation: 101
threading.Timer
expects a function to be passed as its second argument.
One simple way to fix this is:
t = threading.Timer(1.0, lambda: move(x0, y0, x1, y1))
Upvotes: 0
Reputation: 9536
Let's assume your error is the iterable error, as you claim at the top of your post. Then your code is different from what you posted.
Timer()
takes iterable arguments (tuples, lists, etc) or keyword arguments as the third argument.
move(x0, y0, x1, y1)
is None
, as a function without a return statement implicitly returns None
. As the error states, None
is not iterable.
To fix your code, pass in an iterable.
Now let's assume your code is as you posted, and the error is that None
is not callable. In that case, you must pass a function object (remove the parantheses), and then put move()
's arguments as an iterable after (Timer(1.0, move, [x0, y0, x1, y1]
in this case)
Remember, Timer()
takes these arguments:
Timer(time, function, iterable, kwargs)
Edit: you clarified that your error is not the iterable one. Refer to the second example
Upvotes: 2