at backyard

Color my life with the chaos of trouble.

tkinterのdestroyとquitの違いを調べた

tkinterを使っているとき、ふとdestroyとquitの違いはなんぞや?と考えた。

両者は似たような動きをするが、どのように異なるのだろうか?と疑問に思って試しにインターネットで調べてみたら、ズバリな回答がstack overflowにあった。

stackoverflow.com

上の回答を要約すると、 quit()destroy() も動きとしては mainloop を終了させることになるのは変わらないが、その際にウィジェットを破棄するか否かで異なるようだ。
と書いてみたが、どうにも自分は飲み込みが悪いので実際に動作させてみないとイメージが沸かない...なのでコードを書いてみる。

quit()を呼び出した場合、ウィジェットリソースは破棄されない

サンプルは下記。

import tkinter as tk

def main():
    root = tk.Tk()
    root.title("quit sample")
    root.geometry("300x200")

    button = tk.Button(root, text="Exit", command=root.quit)
    button.pack()

    root.mainloop()
    print("===Exit===")
    print("button text: ", button["text"])


if __name__ == "__main__":
    main()

このサンプルを実行すると、下記のようなシンプルな画面が起動する。

f:id:shinshin86:20220221234044p:plain

Exit ボタンを押すと、quit()が呼ばれ、mainloopを抜けた後、

===Exit===
button text:  Exit

と表示されてアプリが終了する。

destroy()を呼び出した場合、ウィジェットリソースは破棄される

さきほどのコードサンプルのうち、Exitボタンを押した際の処理を root.destroy に変更した。

import tkinter as tk

def main():
    root = tk.Tk()
    root.title("destroy sample")
    root.geometry("300x200")

    button = tk.Button(root, text="Exit", command=root.destroy)
    button.pack()

    root.mainloop()
    print("===Exit===")
    print("button text: ", button["text"])


if __name__ == "__main__":
    main()

こちらのアプリを起動して Exit を押すと、 ===Exit=== は表示されるものの、その後にエラーとなる。

===Exit===
・
・
・
_tkinter.TclError: invalid command name ".!button"

これにより、リソースが破棄されているのがわかる。