TclError:无效的命令名称“.4318456072”

时间:2018-04-28 17:39:38

标签: python user-interface animation canvas tkinter

我正在使用tkinter编写一个版本的snake。尝试使用while True循环使画布小部件无限期地移动时,我遇到了一个问题。代码似乎工作正常但我在关闭窗口时在控制台中得到一个异常: Tkinter回调中的例外

Traceback (most recent call last):
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk/Tkinter.py", line 1536, in __call__
    return self.func(*args)
  File "/Users/rachkids/Documents/Coding/Ball Game.py", line 33, in move_ball_right
    canvas.move(ball, xspeed, yspeed)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk/Tkinter.py", line 2416, in move
    self.tk.call((self._w, 'move') + args)
TclError: invalid command name ".4318456072"

以下是使对象移动的功能:

def move_ball_right(event):
    global spaceright
    global spaceleft
    if spaceright != 400:
        while True:
            xspeed = 10
            yspeed = 0
            canvas.move(ball, xspeed, yspeed)
            Tk.update(window1)
            spaceright = spaceright + 10
            spaceleft = spaceleft + 10
            time.sleep(0.25)

到目前为止,这是我的所有代码:

from Tkinter import *
from Tkinter import Canvas
import random
import time

window1 = Tk()
window1.title("Ball Game")
window1.config(background="black")
window1.geometry("400x400")
coord1 = 0
coord2 = 0
coord3 = 20
coord4 = 20
spaceright = 20
spaceleft = 400
spaceup = 400
spacedown = 20
random1 = random.choice([20,30,40,50,60,70,80,90,100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260,270,280,290,300,310,320,330,340,350,360,370,380])
random2 = random1 + 20


def generate_food():
    food = canvas.create_rectangle(random1, random1, random2, random2, fill="red")


def move_ball_right(event):
    global spaceright
    global spaceleft
    if spaceright != 400:
        while True:
            xspeed = 10
            yspeed = 0
            canvas.move(ball, xspeed, yspeed)
            Tk.update(window1)
            spaceright = spaceright + 10
            spaceleft = spaceleft + 10
            time.sleep(0.25)


def move_ball_left (event):
    global spaceright
    global spaceleft
    if spaceleft != 400:
        xspeed = -10
        yspeed = 0
        canvas.move(ball, xspeed, yspeed)
        Tk.update(window1)
        spaceleft = spaceleft - 10
        spaceright = spaceright - 10


def move_ball_down (event):
    global spacedown
    global spaceup
    if spacedown != 400:
        xspeed = 0
        yspeed = 10
        canvas.move(ball, xspeed, yspeed)
        Tk.update(window1)
        spacedown = spacedown + 10
        spaceup = spaceup + 10


def move_ball_up (event):
    global spacedown
    global spaceup
    if spaceup != 400:
        xspeed = 0
        yspeed = -10
        canvas.move(ball, xspeed, yspeed)
        Tk.update(window1)
        spaceup = spaceup - 10
        spacedown = spacedown - 10


canvas = Canvas(window1, width=400, height=400, bg="black", bd=0, highlightthickness=0, relief="ridge")
canvas.pack()
generate_food()
ball = canvas.create_rectangle(coord1, coord2, coord3, coord4, fill="white")
window1.bind('<Right>', move_ball_right)
window1.bind('<Left>', move_ball_left)
window1.bind('<Down>', move_ball_down)
window1.bind('<Up>', move_ball_up)
window1.mainloop()

任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:0)

这是因为当你杀死tkinter窗口时,canvas对象也会被破坏,成为tkinter窗口的子对象(在这种情况下,画布被报告为对象编号.4318456072)。但是while循环仍在运行 - 即使tkinter窗口消失了。但画布对象不存在,从而产生错误。

更正可以包括在canvas.move语句周围放置一个try / expect块,并在发生此异常时导致while循环中断。

特别是,应该捕获与while循环中的tkinter有关的任何内容。这里非常简单的错误检查可能是:

try:
    canvas.move(ball, xspeed, yspeed)
    Tk.update(window1)
except:
    break