2012-11-22 251 views
2

我不明白的方式破壞作品...破壞不破壞

我有一個類子窗口是Tk.Toplevel 的子類,如果這個子窗口中有一個內部的部件

自我.label = Tk.Label(主=自,文本= '這是子窗口: %S !!!!' %自我)

當我破壞子窗口,它不DIE,它窗臺活(我知道這看着子窗口的數組)

銷燬子窗口的唯一方法是調用

德爾self.label

在銷燬方法

import Tkinter as Tk 
import weakref 

root = Tk.Tk() 
subwindows = [] 


def subwindow(): 
    subwindows.append(weakref.ref(SubWindow(root))) 

def list_subwindows(): 
    print 'Subwindows: ', 
    for subwindow in subwindows: 
     sw = subwindow() 
     if sw: 
      print sw, 
    print '' 


class SubWindow(Tk.Toplevel): 
    def __init__(self, window): 
     Tk.Toplevel.__init__(self, master = window) 
     self.label = Tk.Label(master=self, text='This is Sub Window: %s!!!!'%self) 
     self.label.pack() 
#  self.bind('<Destroy>', self._destroy) 


    def _destroy(self, event): 
     try: 
      del self.label 
     except: 
      pass 


bStartWindow = Tk.Button(master=root, text='Start Sub Window', 
         command=subwindow) 
bStartWindow.pack() 

bListSubwindows = Tk.Button(master=root, text='List Active subwindows', 
          command = list_subwindows) 
bListSubwindows.pack() 

root.mainloop() 

爲什麼子窗口沒有被銷燬?

+0

你是如何摧毀這個小工具? –

+0

由你的問題,我想我做錯了,但我只是關閉窗口右上角的X按鈕。我認爲沒有必要直接調用destroy() – fariza

+0

不要從我的問題推斷任何東西。我問,只是因爲你沒有說你是如何摧毀它的。你摧毀的方式決定了發生的事情。點擊窗口裝飾會導致與直接調用'destroy'方法或在窗口小部件上調用'del'相比發生不同的事情。 –

回答

1

由於Tkinter的實現方式,像頂級控件這樣的控件實際上是兩個對象。它是一個python類的實例,它也是一個對象,它是底層Tk庫可以理解的東西。

我沒有仔細看過,但我懷疑該窗口的默認綁定是銷燬小部件,而不是銷燬python類實例。所以,頂層小部件被銷燬,但Subwindow的實例不會立即銷燬。或者更準確地說,它已被破壞,但尚未被垃圾收集。

當它銷燬的一個小部件時,它的所有子部件也被銷燬。我不太清楚爲什麼你認爲標籤沒有被銷燬,因爲我沒有看到任何實際檢查標籤小部件的代碼。你爲什麼認爲標籤沒有被銷燬?

你所看到的僅僅是垃圾收集器沒有運行的證據。小部件已被銷燬,但Tkinter包裝仍然存在。

修改list_windows強制垃圾收集,你會看到該對象確實被摧毀:

def list_subwindows(): 
    import gc 
    gc.collect() 
    print 'Subwindows: ', 
    for subwindow in subwindows: 
     sw = subwindow() 
     if sw: 
      print sw, 
    print '' 
+0

如果您運行代碼,您將看到一個帶有兩個按鈕的窗口,其中一個創建子窗口,另一個列出活動子窗口。活動子窗口的列表列出了每個子窗口對象,它們依然存在於weakref中 – fariza

+0

這不是我擔心的標籤,是我想要銷燬的子窗口對象 – fariza

+0

@fariza:我已更新我的答案。你看到的只是垃圾收集器沒有運行的證據。該對象已被銷燬,當您單擊該按鈕時,該對象還沒有被GC'd。強制垃圾收集和對象將真正消失(但只做爲學習練習;沒有必要在真正的應用程序中做) –