Overriding Tkinter "X" button control (the button that close the window) [duplicate]
When the user presses a close Button
that I created, some tasks are performed before exiting. However, if the user clicks on the [X]
button in the top-right of the window to close the window, I cannot perform these tasks.
How can I override what happens when the user clicks [X]
button?
It sounds as if your save window should be modal.
If this is a basic save window, why are you reinventing the wheel?
Tk
has a tkFileDialog
for this purpose.
If what you want is to override the default behaviour of destroying the window, you can simply do:
root.protocol('WM_DELETE_WINDOW', doSomething) # root is your root window
def doSomething():
# check if saving
# if not:
root.destroy()
This way, you can intercept the destroy()
call when someone closes the window (by any means) and do what you like.
Using the method procotol
, we can redefine the WM_DELETE_WINDOW
protocol by associating with it the call to a function, in this case the function is called 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()
The command you are looking for is wm_protocol
, giving it "WM_DELETE_WINDOW"
as the protocol to bind to. It lets you define a procedure to call when the window manager closes the window (which is what happens when you click the [x]
).
I found a reference on Tkinter here. It's not perfect, but covers nearly everything I ever needed. I figure section 30.3 (Event types) helps, it tells us that there's a "Destroy" event for widgets. I suppose .bind()ing your saving jobs to that event of your main window should do the trick.
You could also call mainwindow.overrideredirect(True) (section 24), which disables minimizing, resizing and closing via the buttons in the title bar.
精彩评论