2

破壊の仕組みがわかりません...

Tk.Toplevel のサブクラスであるクラス SubWindow があります。このサブウィンドウに内部ウィジェットがある場合

self.label = Tk.Label(master=self, text='これはサブ ウィンドウです: %s!!!!'%self)

サブウィンドウを破棄しても、死ぬことはなく、生きているままです(サブウィンドウの配列を見ればわかります)

サブウィンドウを破棄する唯一の方法は、

del self.label

destroy メソッドで。

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()

内部ウィジェットがある場合、サブウィンドウが破棄されないのはなぜですか?

4

1 に答える 1

1

Tkinter の実装方法により、トップレベルなどのウィジェットは実際には 2 つのオブジェクトになります。これは 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 ''
于 2012-11-22T19:12:47.600 に答える