我不明白 destroy 的工作方式...
我有一个 SubWindow 类,它是 Tk.Toplevel 的子类 如果这个子窗口有一个内部小部件
self.label = Tk.Label(master=self, text='This is Sub Window: %s!!!!'%self)
当我销毁子窗口时,它并没有死,它还活着(我知道这个看着子窗口的数组)
销毁子窗口的唯一方法是调用
del 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()
为什么子窗口有内部widget时不销毁?
请您参考如下方法:
由于 Tkinter 的实现方式,像顶层这样的小部件实际上是两个对象。它是 Python 类的一个实例,从某种意义上说,它也是一个对象,因为它是底层 Tk 库可以理解的东西。
我没有仔细看,但我怀疑窗口的默认绑定(bind)是销毁小部件而不是销毁 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 ''
