2012-11-22 198 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。强制垃圾收集和对象将真正消失(但只做为学习练习;没有必要在真正的应用程序中做) –