TclError: неверное имя команды ".4318456072" - PullRequest
0 голосов
/ 28 апреля 2018

Я пишу версию змеи, используя tkinter. Я столкнулся с проблемой при попытке переместить виджет холста на неопределенное время с помощью цикла while True. Код работает нормально, но после закрытия окна я получаю исключение в консоли: Исключение в Tkinter callback

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 голосов
/ 28 апреля 2018

Это потому, что когда вы убиваете окно tkinter, объект canvas также уничтожается, являясь дочерним элементом окна tkinter (в этом случае холст сообщается как номер объекта .4318456072). Но цикл while все еще работает - хотя окно tkinter исчезло. Но объект canvas не существует, что приводит к ошибке.

Исправление может включать в себя помещение блока try / wait вокруг оператора canvas.move и прерывание цикла while при возникновении этого исключения.

В частности, все, что связано с tkinter в цикле while, должно быть перехвачено. Очень тривиальная проверка ошибок здесь может быть:

try:
    canvas.move(ball, xspeed, yspeed)
    Tk.update(window1)
except:
    break
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...