_tkinter。Tcl错误:无法调用"update"命令:应用程序已销毁错误



我有以下代码正常工作,直到我在程序结束时添加了way loop,y基本上试图使循环永远运行(更新屏幕),直到窗口为窗口关闭。

 while 1:
        tk.update_idletasks()
        tk.update()
        time.sleep(0.01)

在将上述代码添加到现有代码中时,程序运行,但是在退出时...提出了此错误:

_tkinter.TclError: can't invoke "update" command: application has been destroyed error

我已经看到了一个类似的问题,但由于这个错误而没有,但是没有一个答案可以帮助我的特定情况。

整个代码如下:

问题/问题:是什么引起此错误,我该如何修复?

from tkinter import *
import random
import time
tk=Tk()
tk.title("My 21st Century Pong Game")
tk.resizable(0,0)
tk.wm_attributes("-topmost",1)
canvas=Canvas(tk,bg="white",width=500,height=400,bd=0,highlightthickness=0)
canvas.pack()
tk.update()

class Ball: #create a ball class
    def __init__(self,canvas,color): #initiliased with the variables/attributes self, canvas, and color
        self.canvas=canvas #set the intiial values for the starting attributes
        self.id=canvas.create_oval(30,30,50,50,fill=color) #starting default values for the ball
        """ Note: x and y coordinates for top left corner and x and y coordinates for the bottom right corner, and finally the fill colour for the oval
        """
        self.canvas.move(self.id,0,0) #this moves the oval to the specified location
    def draw(self): #we have created the draw method but it doesn't do anything yet.
        pass 

ball1=Ball(canvas,'green') #here we are creating an object (green ball) of the class Ball
while 1:
    tk.update_idletasks()
    tk.update()
    time.sleep(0.01)

说明更新:

也值得解释:

主循环是程序的中心部分,怠速已经具有主循环 - 但是,如果您在空闲之外运行此程序,则画布将出现,然后在一秒钟后消失。为了阻止窗口关闭,我们需要动画循环 - 因此,1:.....它在闲置时可以很好地工作,而无需使用1:.... etc)

我同意其他人应该在此处使用mainloop(),但是,如果您想按照我的方式保留原始代码,那就是跟踪布尔值并做while x == True。这样,我们可以将x的值更新为等于 False,这应该使错误发生。

当应用关闭时,我们可以使用protocol()方法来更新布尔值。

如果我们将其添加到您的代码中:

x = True
def update_x():
    global x
    x = False
tk.protocol("WM_DELETE_WINDOW", update_x)

并将您的while语句更改为:

while x == True:
    tk.update_idletasks()
    tk.update()
    time.sleep(0.01)

,您的完整代码可能看起来像这样:

from tkinter import *
import random
import time

tk=Tk()
tk.title("My 21st Century Pong Game")
tk.resizable(0,0)
tk.wm_attributes("-topmost",1)
x = True
def update_x():
    global x
    x = False
tk.protocol("WM_DELETE_WINDOW", update_x)
canvas=Canvas(tk,bg="white",width=500,height=400,bd=0,highlightthickness=0)
canvas.pack()
tk.update()
class Ball:
    def __init__(self,canvas,color):
        self.canvas=canvas
        self.id=canvas.create_oval(30,30,50,50,fill=color)
        """ Note: x and y coordinates for top left corner and x and y coordinates for the bottom right corner, and finally the fill colour for the oval
        """
        self.canvas.move(self.id,0,0)
    def draw(self):
        pass 
ball1=Ball(canvas,'green')
while x == True:
    tk.update_idletasks()
    tk.update()
    time.sleep(0.01)

这将解决您的问题。

重申其他人所说的您真正需要的是mainloop(),而不是您的while i:语句。

mainloop()方法用于您的Tk()实例的循环重置,一旦代码到达表示tk.mainloop()的行,它将是代码的下一个循环。

编写代码的正确方法是仅使用mainloop(),因为它可以为TKINTER实例进行所有更新。

使用mainloop()参见下面的代码:

from tkinter import *
tk=Tk()
tk.title("My 21st Century Pong Game")
tk.resizable(0,0)
tk.wm_attributes("-topmost",1)
canvas=Canvas(tk,bg="white",width=500,height=400,bd=0,highlightthickness=0)
canvas.pack()
tk.update()
class Ball:
    def __init__(self,canvas,color):
        self.canvas=canvas
        self.id=canvas.create_oval(30,30,50,50,fill=color)
        """ Note: x and y coordinates for top left corner and x and y coordinates for the bottom right corner, and finally the fill colour for the oval
        """
        self.canvas.move(self.id,0,0)
    def draw(self):
        pass 
ball1=Ball(canvas,'green')
tk.mainloop()

您正在有效地尝试实现自己的mainloop而不是使用它。

要了解mainloop,您可以在此处阅读有关它。您可以将其视为您添加的新代码的句法抽象;您的while循环。当一个已经存在时,您几乎试图通过制作自己的循环来"更新屏幕"来重新创建轮子!

退出程序时,您可以使用sys.exit()避免错误。

编辑:

替换以下代码:

while 1:
    tk.update_idletasks()
    tk.update()
    time.sleep(0.01)

与此:

tk.mainloop()

您的错误是因为,如它所说,如果窗口已被销毁,则无法更新该窗口。mainloop应该处理此。

退出应用程序时,下次致电update_idletasks时,窗口对象被破坏。然后,您尝试在不存在的窗口上调用update

您需要删除以while开头的所有四行,然后用单行tk.mainloop()替换它们,该行可正确处理窗口的破坏。

另外,如果您很想保留原始代码,则没有理由拨打update_idletasksupdate。前者是后者的子集。

相关内容

最新更新