Skip to main content
 首页 » 编程设计

python之毁不毁

2025年05月04日10cyq1162

我不明白 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 ''