web-dev-qa-db-ja.com

Tkinter "X"ボタンコントロール(ウィンドウを閉じるボタン)のオーバーライド

ユーザーが作成したcloseButtonを押すと、終了する前にいくつかのタスクが実行されます。しかし、ユーザーがウィンドウの右上にある[X]ボタンをクリックしてウィンドウを閉じると、これらのタスクを実行できません。

ユーザーが[X]ボタンをクリックしたときの動作をオーバーライドするにはどうすればよいですか?

26
erkangur

保存ウィンドウは modal のように聞こえます。

これが基本的な保存ウィンドウである場合、なぜホイールを再発明するのですか? Tkには、この目的のために tkFileDialog があります。


ウィンドウを破棄するというデフォルトの動作をオーバーライドする場合は、次のようにするだけです。

_root.protocol('WM_DELETE_WINDOW', doSomething)  # root is your root window

def doSomething():
    # check if saving
    # if not:
    root.destroy()
_

このようにして、誰かが(何らかの手段で)ウィンドウを閉じたときにdestroy()呼び出しをインターセプトして、好きなことを行うことができます。

42
Nick Presta

メソッドprocotolを使用すると、関数の呼び出しに関連付けることでWM_DELETE_WINDOWプロトコルを再定義できます。この場合、関数はon_exitと呼ばれます。

import tkinter as tk
from tkinter import messagebox


class App(tk.Tk):

    def __init__(self):
        tk.Tk.__init__(self)
        self.title("Handling WM_DELETE_WINDOW protocol")
        self.geometry("500x300+500+200")
        self.make_topmost()
        self.protocol("WM_DELETE_WINDOW", self.on_exit)

    def on_exit(self):
        """When you click to exit, this function is called"""
        if messagebox.askyesno("Exit", "Do you want to quit the application?"):
            self.destroy()

    def center(self):
        """Centers this Tk window"""
        self.eval('tk::PlaceWindow %s center' % app.winfo_pathname(app.winfo_id()))

    def make_topmost(self):
        """Makes this window the topmost window"""
        self.lift()
        self.attributes("-topmost", 1)
        self.attributes("-topmost", 0)


if __name__ == '__main__':
    App().mainloop()
6
The Demz

あなたが探しているコマンドはwm_protocol、それを与える"WM_DELETE_WINDOW"をバインドするプロトコルとして。ウィンドウマネージャーがウィンドウを閉じたときに呼び出すプロシージャを定義できます([x])。

2
Bryan Oakley

Tkinter here のリファレンスを見つけました。それは完璧ではありませんが、私が今までに必要としたほぼすべてをカバーしています。セクション30.3(イベントタイプ)が役立つと思いますが、ウィジェットには「破棄」イベントがあることがわかります。私はあなたのメインウィンドウのそのイベントにあなたの保存ジョブを.bind()することがトリックをするべきだと思います。

Mainwindow.overrideredirect(True)(セクション24)を呼び出すこともできます。これにより、タイトルバーのボタンを介して最小化、サイズ変更、および閉じることができなくなります。

1
user395760