【问题标题】:Python : TclError: invalid command name ".!canvas"Python:TclError:无效的命令名称“.!canvas”
【发布时间】:2021-07-17 10:28:07
【问题描述】:

我正在编写一个自定义游戏来学习 python。当我运行游戏并测试错误时,没有崩溃,但关闭窗口后,有时会出现此错误

TclError: invalid command name ".!canvas" 

有时不会,如果出现此错误代码,我必须重新打开一个新控制台,否则下一次运行将崩溃并自动重新启动控制台。我怎样才能防止这种情况发生?

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

"""
Created on Thu Jul  8 18:34:52 2021

@author: Rudolf
"""

import turtle
import random
import time

#képernyő
wn = turtle.Screen()
wn.title("asd")
wn.bgcolor("black")
wn.setup(width=800, height=600)
wn.tracer(0,0)
#turtle.register_shape("asd.gif")

#bullet
bullet = turtle.Turtle()
bullet.speed(0)
bullet.color("blue")
bullet.shape("square")
bullet.shapesize(stretch_wid=1,stretch_len=1)
bullet.penup()
bullet.goto(1000,1000)
bullet.dx = 20

#vonal
vonal = turtle.Turtle()
vonal.speed(0)
vonal.color("white")
vonal.shape("square")
vonal.penup()
vonal.shapesize(stretch_wid=40,stretch_len=0.35)
vonal.goto(-3.5,0)

#első player
testone = turtle.Turtle()
testone.speed(0)
testone.color("white")
testone.shape("square")
testone.penup()
testone.shapesize(stretch_wid=3,stretch_len=3)
testone.goto(-200, 0)

#második player
testtwo = turtle.Turtle()
testtwo.speed(0)
testtwo.color("white")
testtwo.shape("square")
testtwo.penup()
testtwo.shapesize(stretch_wid=3,stretch_len=3)
testtwo.goto(200, 0)

#ammo
ammoone = turtle.Turtle()
ammoone.speed(0)
ammoone.color("red")
ammoone.shape("circle")
ammoone.penup()
ammoone.shapesize(stretch_wid=2,stretch_len=2)
ammoone.goto(random.randint(-380,-10),random.randint(-280,280))

#pont
pont = turtle.Turtle()
pont.speed(0)
pont.shape("square")
pont.color("white")
pont.hideturtle()
pont.penup()
pont.goto(0, -260)
pont.write("pont : 0  pont : 0", align="center", font=("Courier", 24, "normal"))

#ammo count
ammo = turtle.Turtle()
ammo.color("white")
ammo.shape("square")
ammo.penup()
ammo.hideturtle()
ammo.goto(0, 260)
ammo.write("Player 1 Ammo : 0 Player 2 Ammo : 0",align = "center", font = ("Courier", 24,"normal"))

a = 0
b = 0
c = 0
d = 0

#1-es player irányitás
def up():
        height = 300
        move = 80
        y = testone.ycor()
        if y < height :
            if y + move > height - 19:
                y = height - 19
                testone.sety(y)
            else:
                y += move
                testone.sety(y)
    
def down():
        height = -300
        move = 80 
        y = testone.ycor()
        if y > height :
            if y - move < height + 29:
                y = height + 29
                testone.sety(y)
            else:
                y -= move
                testone.sety(y)   

def left():
        width = -400
        move = 80 
        a = 22
        x = testone.xcor()
        if x > width :
            if x - move < width + a:
                x = width + a
                testone.setx(x)
            else:
                x -= move
                testone.setx(x)

def right():
        width = 0
        move = 80 
        a = 29
        x = testone.xcor()
        if x < width :
            if x + move > width - a:
                x = width -a
                testone.setx(x)
            else:
                x += move
                testone.setx(x)
                
def fire():
        global a
        if bullet.xcor() > 1000 and bullet.ycor() == 1000:
           
            if a > 0:
                a -= 1
                bullet.goto(testone.xcor(),testone.ycor())
    
#2-es player irányitás               
def uptwo():
        height = 300
        move = 80
        y = testtwo.ycor()
        if y < height :
            if y + move > height - 19:
                y = height - 19
                testtwo.sety(y)
            else:
                y += move
                testtwo.sety(y)
    
def downtwo():
        height = -300
        move = 80 
        y = testtwo.ycor()
        if y > height :
            if y - move < height + 29:
                y = height + 29
                testtwo.sety(y)
            else:
                y -= move
                testtwo.sety(y)   

def lefttwo():
        width = 0
        move = 80 
        a = 22
        x = testtwo.xcor()
        if x > width :
            if x - move < width + a:
                x = width + a
                testtwo.setx(x)
            else:
                x -= move
                testtwo.setx(x)

def righttwo():
        width = 400
        move = 80 
        a = 29
        x = testtwo.xcor()
        if x < width :
            if x + move > width - a:
                x = width -a
                testtwo.setx(x)
            else:
                x += move
                testtwo.setx(x)
    
wn.listen()   
wn.onkeypress(up,"w")
wn.onkeypress(down,"s")
wn.onkeypress(left,"a")
wn.onkeypress(right,"d")

wn.onkeypress(uptwo,"Up")
wn.onkeypress(downtwo,"Down")
wn.onkeypress(lefttwo,"Left")
wn.onkeypress(righttwo,"Right")

run = True

while run:
    wn.update()
    bullet.setx(bullet.xcor() + bullet.dx)

    if ammoone.xcor() + 30 > testone.xcor() - 30 and ammoone.xcor() - 30 < testone.xcor() + 30 and ammoone.ycor() + 30 > testone.ycor() - 30 and ammoone.ycor() - 30 < testone.ycor() + 30:
        
        a += 1
        
        ammoone.goto(random.randint(-380,-10),random.randint(-280,280))
        ammo.clear()
        ammo.write("Player 1 Ammo : {} Player 2 Ammo : {}".format(a, b),align = "center", font = ("Courier", 24,"normal"))
        
    if bullet.xcor() > 1000 and bullet.ycor() == 1000:
        wn.onkeypress(fire,"q")
    
    if testtwo.xcor() + 30 > bullet.xcor() - 30 and testtwo.xcor() - 30 < bullet.xcor() + 30 and testtwo.ycor() + 30 > bullet.ycor() - 30 and testtwo.ycor() - 30 < bullet.ycor() + 30:
                 
        c += 1
        bullet.goto(1000,1000)
    
    if bullet.xcor() > 400 and bullet.xcor() < 500:
        bullet.goto(1000,1000)
                            
    ammo.clear()
    ammo.write("Player 1 Ammo : {} Player 2 Ammo : {}".format(a, b),align = "center", font = ("Courier", 24,"normal"))   
    pont.clear()
    pont.write("pont : {}  pont : {}".format(c, d), align="center", font=("Courier", 24, "normal"))

    wn.update()

wn.exitonclick()

【问题讨论】:

    标签: python canvas


    【解决方案1】:

    您可以将无限循环替换为将使用wn.ontimer 函数的函数,该函数将使用wn.mainloop() 函数连续调用,来自:

    run = True
    
    while run:
        wn.update()
        bullet.setx(bullet.xcor() + bullet.dx)
    
        if ammoone.xcor() + 30 > testone.xcor() - 30 and ammoone.xcor() - 30 < testone.xcor() + 30 and ammoone.ycor() + 30 > testone.ycor() - 30 and ammoone.ycor() - 30 < testone.ycor() + 30:
            
            a += 1
            
            ammoone.goto(random.randint(-380,-10),random.randint(-280,280))
            ammo.clear()
            ammo.write("Player 1 Ammo : {} Player 2 Ammo : {}".format(a, b),align = "center", font = ("Courier", 24,"normal"))
            
        if bullet.xcor() > 1000 and bullet.ycor() == 1000:
            wn.onkeypress(fire,"q")
        
        if testtwo.xcor() + 30 > bullet.xcor() - 30 and testtwo.xcor() - 30 < bullet.xcor() + 30 and testtwo.ycor() + 30 > bullet.ycor() - 30 and testtwo.ycor() - 30 < bullet.ycor() + 30:
                     
            c += 1
            bullet.goto(1000,1000)
        
        if bullet.xcor() > 400 and bullet.xcor() < 500:
            bullet.goto(1000,1000)
                                
        ammo.clear()
        ammo.write("Player 1 Ammo : {} Player 2 Ammo : {}".format(a, b),align = "center", font = ("Courier", 24,"normal"))   
        pont.clear()
        pont.write("pont : {}  pont : {}".format(c, d), align="center", font=("Courier", 24, "normal"))
    
        wn.update()
    

    到:

    def run():
        wn.update()
        bullet.setx(bullet.xcor() + bullet.dx)
    
        if ammoone.xcor() + 30 > testone.xcor() - 30 and ammoone.xcor() - 30 < testone.xcor() + 30 and ammoone.ycor() + 30 > testone.ycor() - 30 and ammoone.ycor() - 30 < testone.ycor() + 30:
    
            a += 1
    
            ammoone.goto(random.randint(-380,-10),random.randint(-280,280))
            ammo.clear()
            ammo.write("Player 1 Ammo : {} Player 2 Ammo : {}".format(a, b),align = "center", font = ("Courier", 24,"normal"))
    
        if bullet.xcor() > 1000 and bullet.ycor() == 1000:
            wn.onkeypress(fire,"q")
    
        if testtwo.xcor() + 30 > bullet.xcor() - 30 and testtwo.xcor() - 30 < bullet.xcor() + 30 and testtwo.ycor() + 30 > bullet.ycor() - 30 and testtwo.ycor() - 30 < bullet.ycor() + 30:
    
            c += 1
            bullet.goto(1000,1000)
    
        if bullet.xcor() > 400 and bullet.xcor() < 500:
            bullet.goto(1000,1000)
    
        ammo.clear()
        ammo.write("Player 1 Ammo : {} Player 2 Ammo : {}".format(a, b),align = "center", font = ("Courier", 24,"normal"))   
        pont.clear()
        pont.write("pont : {}  pont : {}".format(c, d), align="center", font=("Courier", 24, "normal"))
    
        wn.update()
        wn.ontimer(run)
    
    run()
    mainloop()
    

    【讨论】:

    • 我做到了,创建了全局变量,现在程序出现了这个错误:TclError: can't invoke "bind" command: application has been destroyed, but it does完全一样,必须重新启动控制台,否则它会在下一次运行时崩溃
    • @Brogerr 你可以试试:try: while run...except: pass
    【解决方案2】:

    我做到了,创建了全局变量,现在程序出现了这个错误:TclError: can't invoke "bind" command: application has been destroyed,但它完全一样,必须重新启动控制台,否则它会崩溃在下一次运行时

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-15
      • 2011-05-14
      • 2020-01-24
      相关资源
      最近更新 更多