2013-03-09 77 views
4

在一個類中,在一個函數中我創建一個Tkinter畫布。這個函數被另一個類調用,我想讓Tkinter窗口彈出30秒,然後關閉它自己。我把它稱之爲一段時間後自動關閉窗口

master.mainloop() 
time.sleep(30) 
master.destroy() 

但我得到一個錯誤

"elf.tk.call('destroy', self._w) _tkinter.TclError: can't invoke "destroy" command: application has been destroyed"

因此,如何能我把它關閉本身?

+1

你需要什麼意思運行與事件循環GUI某種教程,因爲直到你得到,你要繼續運行陷入這樣的問題而不理解它們。 (對不起,我沒有推薦,但也許有人會這樣做。)值得注意的是,網絡服務器和除GUI應用以外的許多其他類型的程序也是圍繞事件循環建立的,所以這是理解一個非常關鍵的事情在玩具系統之外的編程中。 – abarnert 2013-03-09 01:57:28

回答

12

請勿使用tkinter使用time.sleep()。相反,請在要關閉的窗口小部件上調用功能after

這是最簡單的例子:

import tkinter as tk 

w = tk.Tk() 
w.after(30000, lambda: w.destroy()) # Destroy the widget after 30 seconds 
w.mainloop() 
+0

作爲tk和tk.Tk()的重要性是什麼,只是重命名,所以它更容易寫? – EasilyBaffled 2013-03-09 02:04:16

+0

@EasilyBaffled是的,['import as'](http://www.python.org/dev/peps/pep-0221/)用於避免名稱衝突,並縮短名稱模塊。我在Tkinter中使用它非常多,但是對於這個例子'從Tkinter import Tk'並且使用'w = Tk()'也是有效的。 – 2013-03-09 02:16:30

+0

@SasilyBaffled:將Tkinter導入爲tk的另一個原因是您可以將代碼移植到3.x,只需將第一行更改爲「import tinter as tk」,而無需更改引用模塊的所有其他位置。 – abarnert 2013-03-09 02:21:22

4

這裏的問題是mainloop()在GUI關閉之前不會返回。

因此,30秒圖形用戶界面已經關閉並摧毀自己,你試圖摧毀它。顯然這失敗了。

但是,您不能在主循環內移動sleepdestroy調用,因爲如果在主循環中間sleep,GUI將凍結。

所以,你需要某種不會停止主循環的計時器。 tkinter包含完全用於此目的的after方法。 This answer給出了一個使用它的詳細例子。

相關問題