I'm using python 3.4.1 with windows and when I close my Tkinter I obtain an error message about move tkinter function. The app works fine, but when I close my app the shell reports me this bug message:
C:\Python34\python.exe "E:/ProgramasPython3/Programas TKinter/JuegoPong/Pong.py"
Traceback (most recent call last):
File "E:/ProgramasPython3/Programas TKinter/JuegoPong/Pong.py", line 96, in <module>
main()
File "E:/ProgramasPython3/Programas TKinter/JuegoPong/Pong.py", line 89, in main
pelota.dibujar()
File "E:/ProgramasPython3/Programas TKinter/JuegoPong/Pong.py", line 35, in dibujar
self.canvas.move(self.id, self.x, self.y)
File "C:\Python34\lib\tkinter\__init__.py", line 2398, in move
self.tk.call((self._w, 'move') + args)
_tkinter.TclError: invalid command name ".42952128"
Process finished with exit code 1
This is my code:
#!/usr/bin/env python34
from tkinter import (Tk, Frame, Canvas)
import random
import time as time
class Pelota(Frame):
def __init__(self, canvas, raqueta, color):
Frame.__init__(self, master=None)
self.canvas = canvas
self.raqueta = raqueta
self.color = color
self.id = self.canvas.create_oval(10.0, 10.0, 25.0, 25.0, fill=self.color)
self.canvas.move(self.id, 245.0, 100.0)
empezar = [-3, -2, -1, 0, 1, 2, 3]
random.shuffle(empezar)
self.x = empezar[0]
self.y = -3.0
self.canvas_height = self.canvas.winfo_reqheight()
self.canvas_width = self.canvas.winfo_reqwidth()
def golpea_raqueta(self, pos):
raqueta_pos = self.canvas.coords(self.raqueta.id)
if pos[2] >= raqueta_pos[0] and pos[0] <= raqueta_pos[2]:
if raqueta_pos[1] <= pos[3] <= raqueta_pos[3]:
return True
return False
def dibujar(self):
self.canvas.move(self.id, self.x, self.y)
pos = self.canvas.coords(self.id)
if pos[1] <= 0.0:
self.y = 3.0
elif pos[3] >= self.canvas_height:
self.y = -3.0
elif self.golpea_raqueta(pos):
self.y = -3.0
elif pos[0] <= 0.0:
self.x = 3.0
elif pos[2] >= self.canvas_width:
self.x = -3.0
class Raqueta(Frame):
def __init__(self, canvas, color):
Frame.__init__(self, master=None)
self.canvas = canvas
self.color = color
self.x = 0.0
self.id = self.canvas.create_rectangle(0.0, 0.0, 100.0, 10.0, fill=self.color)
self.canvas.move(self.id, 200.0, 300.0)
self.canvas_width = self.canvas.winfo_reqwidth()
self.canvas.bind_all('<KeyPress-Left>', self.to_left)
self.canvas.bind_all('<KeyPress-Right>', self.to_right)
def dibujar(self):
self.canvas.move(self.id, self.x, 0.0)
pos = self.canvas.coords(self.id)
if pos[0] <= 0.0:
self.x = 0.0
elif pos[2] >= self.canvas_width:
self.x = 0.0
def to_left(self, evt):
self.x = -2.0
def to_right(self, evt):
self.x = 2.0
def main():
tk = Tk()
tk.title('Mi Pong')
canvas = Canvas(tk, width=500, height=400, bd=0, highlightthickness=0)
raqueta = Raqueta(canvas, 'blue')
pelota = Pelota(canvas, raqueta, 'red')
tk.resizable(0, 0)
tk.wm_attributes('-topmost', 1)
tk.update()
canvas.pack()
while 1:
pelota.dibujar()
raqueta.dibujar()
tk.update_idletasks()
tk.update()
time.sleep(0.01)
main()
The App is an easy Pong game.
Pelota is Ball Raqueta is Tennis Racket dibujar is plot golpea raqueta is knock tennis racket
Thanks
whileloop at the end tries to do another update after the GUI elements have been disposed.try/except, so the error is not shown. After all, as you said, it works nonetheless. A cleaner solution would be to do away with that loop and use theaftermethod of tkinter widgets instead, to have them update themselves.