2017-02-23 37 views
1

我已经尝试过关闭在互联网上可以找到的tkinter窗口的各种方法。我问这个问题的唯一原因,即使已经有很多次的问题了,但我仍然无法使它工作。经过一段时间后退出tkinter窗口?

基本上,我正在做一个简单的'倒计时'游戏(如电视节目),其中涉及一个大型30秒tkinter'计时器'。该号码正确滴答下来,但程序不会继续,除非用户手动关闭该窗口。显然,这首先打败了计时器的目的,但是如何在需要时自动关闭呢?

这是一个非常简单的例子,不工作:

# python 3.5.2  

from tkinter import * 

root = Tk() 
root.title("Test") 
root.mainloop() 

# root.destroy()/root.quit() <== neither of these are effective 

print("The window has now been closed") ## not unless the user crosses it off! 

我尝试使用“后”的方法。首先,我尝试了'root.after(30000,destroy())',然后,为了防万一,我在创建了一个名为'window_closer()'的程序'destroy_closer()'后尝试'root.after(30000,window_closer)'。我假设没有任何区别。这是一种耻辱,因为我成功了,这将是理想的。我也尝试创建一个框架,然后'摧毁'框架,但虽然它可能会禁用小部件,但它实际上并没有关闭窗口(如在,交叉它)。当我尝试'root.quit()'时,什么都没有发生。用'root.destroy()',我得到错误消息'tkinter.TclError:不能调用'销毁'命令:应用程序已被销毁'。显然,这与主循环()有关,但我并没有真正理解它,尽管已经使用了它,并且查看了其他人的答案。

我错过了什么吗?任何帮助将非常感激!

回答

3

在您的代码中,您在调用mainloop后试图运行代码。 mainloop将不会返回,直到窗口已被销毁,所以任何尝试后,修改窗口将失败,“应用程序已被销毁”的错误。

您是对的,您需要使用after来安排销毁,并且您需要使用destroy来造成销毁。关于after要记住的重要事项是,您必须将其参考给一个函数。如果您需要将参数传递给该函数,那么可以在调用after时将其指定为附加参数。

换句话说:

root.after(1000, root.destroy()) 

是完全一样的:

result = root.destroy() 
root.after(1000, result) 

相反,你需要调用destroy没有括号。在绝对简单的情况下,你的程序应该是这样的:

import tkinter as tk 

root = tk.Tk() 
root.after(10000, root.destroy) 
root.mainloop() 

如果你想更新倒计时,你可以调用自己的函数每一秒,当倒计时蜿蜒而下销毁窗口。

下面是一个例子:

import tkinter as tk 

def countdown(time): 
    if time == -1: 
     root.destroy() 
    else: 
     if time == 0: 
      label.configure(text="BOOM") 
     else: 
      label.configure(text="time remaining: %d seconds" % time) 

     root.after(1000, countdown, time-1) 

root = tk.Tk() 
label = tk.Label(root, width=30) 
label.pack(padx=20, pady=20) 
countdown(10) 

root.mainloop() 
+1

我知道我不应该让多余的意见,但非常感谢!这完全奏效 - 我不敢相信我以前找不到这个解释!我不把这个标记为“有用”的唯一原因是我只有1个声望! + 1反正! –