python 执行时命令名无效(“after”脚本)

5cg8jx4n  于 12个月前  发布在  Python
关注(0)|答案(6)|浏览(107)

如何解决这个问题?我正在运行这段代码,窗口被创建,但在控制台上出现错误消息。我认为问题的事实是“之后”循环没有终止,但窗口已经被销毁。
代码:

import Tkinter as tk
import time

class App():
    def __init__(self):
        self.root = tk.Tk()
        self.label = tk.Label(text="")
        self.label.pack()
        self.update_clock()
        self.root.mainloop()

    def update_clock(self):
        now = time.strftime("%H:%M:%S")
        self.label.configure(text=now)
        self.root.after(1000, self.update_clock)

app=App()

字符串
控制台中的消息:

invalid command name "66120320callit"
while executing
"66120320callit"
("after" script)


对不起,我的小信息在第一篇文章。我使用Spyder IDE,和错误看到在Spyder控制台,其中重复运行我的代码。描述这个错误,我发现在python错误跟踪器为“等待_变量挂起退出”

ee7vknir

ee7vknir1#

如果你销毁窗口,任何已经被调度的“之后”作业都可能运行。如果窗口被销毁,并且这个作业与一个已经被删除的小部件交互,你会得到这个错误。
您可以在代码周围放置一个try并忽略这样的错误,在尝试配置它之前检查窗口是否存在,或者在主窗口被销毁时放置一个处理程序以删除任何挂起的“之后”作业。

5lhxktic

5lhxktic2#

TL;DR:使用tkinter.Tk.quit()

背景

我也收到了这些“错误”。它们不是真正的异常,只是在运行单元测试时在终端中看到垃圾邮件令人讨厌。
我尝试了很多方法,包括在tkinter.Tk中覆盖after方法来跟踪任何排队的方法,然后在调用tkinter.Tk.destroy()之前自动调用tkinter.Tk.after_cancel(),@GabrielStaples评论道。
因此,即使在调用destroy()时没有排队的after方法,我也会得到这些错误。

我的解决方案

对我有效的是调用tkinter.Tk.quit()而不是destroy()来销毁窗口。我读到quit()不会停止mainloop,但它看起来很好。在quit()被调用之后,after排队的任何方法都不会被调用。
也许有人能解释一下我不知道的后果

omvjsjqw

omvjsjqw3#

我遇到这个问题是因为我的模块名为“setup”,我也有一个setup.py文件。当调用setup.py somecommand时,你会得到“无效的命令名'somecommand'"。

dly7yett

dly7yett4#

我遇到了这个问题,并通过使用普通Python的exit()而不是Tkinter的root.destroy()tkinter.Tk.quit()解决了这个问题。

lpwwtiir

lpwwtiir5#

对我有用的是创建一个退出按钮,当点击时运行一个函数,该函数将只有下面的2行:

self.withdraw()
self.quit()

字符串
这允许GUI成功关闭,然后继续运行脚本中的其余代码(如果有的话)。
将上面的代码编辑为下面的代码为我修复了它:

import tkinter as tk
import time

class App(tk.Tk):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.label = tk.Label(text="")
        self.label.pack()
        
        self.buttonCloseWindow = tk.Button(self, text='Close Window', command=self.close_window)
        self.buttonCloseWindow.pack()
        
        self.update_clock()
        self.mainloop()

    def close_window(self):
        self.withdraw()
        self.quit()

    def update_clock(self):
        now = time.strftime("%H:%M:%S")
        self.label.configure(text=now)
        self.after(1000, self.update_clock)

app=App()


希望这对你有帮助!

bmp9r5qi

bmp9r5qi6#

这个问题的一个可能的解决方案是定义一个protocol,当窗口被删除(关闭)WM_DELETE_WINDOW。在我的例子中,我用一个Yes/No消息框提示用户,以确保关闭不是意外的。但是如果你只是测试,你可以删除它,关闭按钮将withdraw()quit()应用程序。

import tkinter as tk
import tkinter.messagebox
import time

class App(tk.Tk):
    def __init__(self):
        super().__init__()
        self.label = tk.Label(text="")
        self.label.pack()
        self.update_clock()

    def update_clock(self):
        now = time.strftime("%H:%M:%S")
        self.label.configure(text=now)
        self.after(1000, self.update_clock)

def on_closing():
    response=tkinter.messagebox.askyesno('Exit','Are you sure you want to exit?')
    if response:
        app.withdraw()
        app.quit()

if __name__ == "__main__":
    app = App()
    app.protocol("WM_DELETE_WINDOW", on_closing)
    app.mainloop()

字符串

相关问题