How do I handle the window close event in Tkinter? How do I handle the window close event in Tkinter? tkinter tkinter

How do I handle the window close event in Tkinter?


Tkinter supports a mechanism called protocol handlers. Here, the term protocol refers to the interaction between the application and the window manager. The most commonly used protocol is called WM_DELETE_WINDOW, and is used to define what happens when the user explicitly closes a window using the window manager.

You can use the protocol method to install a handler for this protocol (the widget must be a Tk or Toplevel widget):

Here you have a concrete example:

import tkinter as tkfrom tkinter import messageboxroot = tk.Tk()def on_closing():    if messagebox.askokcancel("Quit", "Do you want to quit?"):        root.destroy()root.protocol("WM_DELETE_WINDOW", on_closing)root.mainloop()


Matt has shown one classic modification of the close button.
The other is to have the close button minimize the window.
You can reproduced this behavior by having the iconify method
be the protocol method's second argument.

Here's a working example, tested on Windows 7 & 10:

# Python 3import tkinterimport tkinter.scrolledtext as scrolledtextroot = tkinter.Tk()# make the top right close button minimize (iconify) the main windowroot.protocol("WM_DELETE_WINDOW", root.iconify)# make Esc exit the programroot.bind('<Escape>', lambda e: root.destroy())# create a menu bar with an Exit commandmenubar = tkinter.Menu(root)filemenu = tkinter.Menu(menubar, tearoff=0)filemenu.add_command(label="Exit", command=root.destroy)menubar.add_cascade(label="File", menu=filemenu)root.config(menu=menubar)# create a Text widget with a Scrollbar attachedtxt = scrolledtext.ScrolledText(root, undo=True)txt['font'] = ('consolas', '12')txt.pack(expand=True, fill='both')root.mainloop()

In this example we give the user two new exit options:
the classic File → Exit, and also the Esc button.


Depending on the Tkinter activity, and especially when using Tkinter.after, stopping this activity with destroy() -- even by using protocol(), a button, etc. -- will disturb this activity ("while executing" error) rather than just terminate it. The best solution in almost every case is to use a flag. Here is a simple, silly example of how to use it (although I am certain that most of you don't need it! :)

from Tkinter import *def close_window():  global running  running = False  # turn off while loop  print( "Window closed")root = Tk()root.protocol("WM_DELETE_WINDOW", close_window)cv = Canvas(root, width=200, height=200)cv.pack()running = True;# This is an endless loop stopped only by setting 'running' to 'False'while running:   for i in range(200):     if not running:         break    cv.create_oval(i, i, i+1, i+1)    root.update() 

This terminates graphics activity nicely. You only need to check running at the right place(s).