125

How do I end a Tkinter program? Let's say I have this code:

from Tkinter import *

def quit():
    # code to exit

root = Tk()
Button(root, text="Quit", command=quit).pack()
root.mainloop()

How should I define the quit function to exit my application?

Stevoisiak
  • 23,794
  • 27
  • 122
  • 225
Matt Gregory
  • 8,074
  • 8
  • 33
  • 40

17 Answers17

178

You should use destroy() to close a Tkinter window.

from Tkinter import * 
#use tkinter instead of Tkinter (small, not capital T) if it doesn't work
#as it was changed to tkinter in newer Python versions

root = Tk()
Button(root, text="Quit", command=root.destroy).pack() #button to close the window
root.mainloop()

Explanation:

root.quit()

The above line just bypasses the root.mainloop(), i.e., root.mainloop() will still be running in the background if quit() command is executed.

root.destroy()

While destroy() command vanishes out root.mainloop(), i.e., root.mainloop() stops. <window>.destroy() completely destroys and closes the window.

So, if you want to exit and close the program completely, you should use root.destroy(), as it stops the mainloop() and destroys the window and all its widgets.

But if you want to run some infinite loop and don't want to destroy your Tkinter window and want to execute some code after the root.mainloop() line, you should use root.quit(). Example:

from Tkinter import *
def quit():
    global root
    root.quit()

root = Tk()
while True:
    Button(root, text="Quit", command=quit).pack()
    root.mainloop()
    #do something

See What is the difference between root.destroy() and root.quit()?.

The Amateur Coder
  • 789
  • 3
  • 11
  • 33
aki92
  • 2,064
  • 2
  • 14
  • 12
  • 2
    If root.quit() is used, how can the window be found again later in a different script to be destroyed (so as not to continue using system resources)? – Raj Jun 29 '16 at 00:14
  • 5
    Your first statement is false. calling `quit` will destroy all widgets; if the widgets are destroyed, `mainloop` will exit. – Bryan Oakley Nov 12 '16 at 00:38
  • 1
    After some research I believe this also applies to ALL code being executed. So if you have a mainloop() of TKinter in a command line script, use root.quit() and not root.destroy(), otherwise your command line script will not continue executing code after mainloop(). I tested this and it works for me (I am aware that TKinter is not intended to be used in such a design, nevertheless, it works) – Alex Dec 20 '17 at 06:30
  • is it a good solution to destroy the Tkinter window many times and start many times – Nitesh Waghmare Feb 18 '20 at 11:36
  • im going to be calling lots of windows(with the same name) so how would this work in that case? – BurnDownTheWorld May 17 '21 at 13:35
46
def quit()
    root.quit()

or

def quit()
    root.destroy()
Smart Manoj
  • 5,230
  • 4
  • 34
  • 59
Matt Gregory
  • 8,074
  • 8
  • 33
  • 40
  • does any one know which method is more 'correct' or is it a case of one is more readable than another – Opal May 07 '11 at 03:09
  • 8
    sorry, i've found the answer and just thought i'd share it. It is better to use `root.destroy()` as it terminates the main program loop. See: [http://www.daniweb.com/software-development/python/threads/66698](http://www.daniweb.com/software-development/python/threads/66698/299275#post299275) – Opal May 07 '11 at 03:13
  • 1
    destroy() is the method to go to if you want to close a open winodw. If you want to close all use quit() – Sheshan Gamage May 20 '21 at 08:06
  • @SheshanGamage `.quit` doesn't close a window, it stops the `.mainloop` which terminates the program if the `.mainloop` is at the end of the program. `.destroy` is the only one that destroys any windows, apart from the python interpreter shutting down. – TheLizzard Nov 27 '22 at 10:28
18
import tkinter as tk

def quit(root):
    root.destroy()

root = tk.Tk()
tk.Button(root, text="Quit", command=lambda root=root:quit(root)).pack()
root.mainloop()
Adriaan
  • 17,741
  • 7
  • 42
  • 75
7

I think you wrongly understood the quit function of Tkinter. This function does not require you to define.

First, you should modify your function as follows:

from Tkinter import *
root = Tk()
Button(root, text="Quit", command=root.quit).pack()
root.mainloop()

Then, you should use '.pyw' suffix to save this files and double-click the '.pyw' file to run your GUI, this time, you can end the GUI with a click of the Button, and you can also find that there will be no unpleasant DOS window. (If you run the '.py' file, the quit function will fail.)

C8H10N4O2
  • 18,312
  • 8
  • 98
  • 134
7

Illumination in case of confusion...

def quit(self):
    self.destroy()
    exit()

A) destroy() stops the mainloop and kills the window, but leaves python running

B) exit() stops the whole process

Just to clarify in case someone missed what destroy() was doing, and the OP also asked how to "end" a tkinter program.

Martin Guiles
  • 71
  • 1
  • 1
4

The usual method to exit a Python program:

sys.exit()

(to which you can also pass an exit status) or

raise SystemExit

will work fine in a Tkinter program.

dF.
  • 74,139
  • 30
  • 130
  • 136
  • 6
    The question was about closing a tkinter window, not a program that uses tkinter. – kevr Jan 30 '20 at 03:00
4

In case anyone wants to bind their Escape button to closing the entire GUI:

master = Tk()
master.title("Python")

def close(event):
    sys.exit()

master.bind('<Escape>',close)
master.mainloop()
Nukyi
  • 51
  • 5
3

The easiest way would be to click the red button (leftmost on macOS and rightmost on Windows). If you want to bind a specific function to a button widget, you can do this:

class App:
    def __init__(self, master)
        frame = Tkinter.Frame(master)
        frame.pack()
        self.quit_button = Tkinter.Button(frame, text = 'Quit', command = frame.quit)
        self.quit_button.pack()

Or, to make things a little more complex, use protocol handlers and the destroy() method.

import tkMessageBox

def confirmExit():
    if tkMessageBox.askokcancel('Quit', 'Are you sure you want to exit?'):
        root.destroy()
root = Tk()
root.protocol('WM_DELETE_WINDOW', confirmExit)
root.mainloop()
Ian Gabaraev
  • 101
  • 1
  • 8
3

you only need to type this:

root.destroy()

and you don't even need the quit() function cause when you set that as commmand it will quit the entire program.

BruhDev
  • 86
  • 7
  • No, it will destroy all the widgets and return from the call to `root.mainloop()`. But any code that you might have following that call will execute. That is *not* the same thing as quitting the entire program. – Booboo Nov 15 '21 at 14:07
2

you dont have to open up a function to close you window, unless you're doing something more complicated:

from Tkinter import *

root = Tk()
Button(root, text="Quit", command=root.destroy).pack()
root.mainloop()
Gonzalez
  • 68
  • 5
1

In idlelib.PyShell module, root variable of type Tk is defined to be global

At the end of PyShell.main() function it calls root.mainloop() function which is an infinite loop and it runs till the loop is interrupted by root.quit() function. Hence, root.quit() will only interrupt the execution of mainloop

In order to destroy all widgets pertaining to that idlelib window, root.destroy() needs to be called, which is the last line of idlelib.PyShell.main() function.

RAD
  • 31
  • 3
1

I normally use the default tkinter quit function, but you can do your own, like this:

from tkinter import *
from tkinter.ttk import *

window = Tk()
window.geometry('700x700') # 700p x 700p screen

def quit(self):
    proceed = messagebox.askyesno('Quit', 'Quit?')
    proceed = bool(proceed) # So it is a bool

    if proceed:
        window.quit()
    else:
        # You don't really need to do this
        pass

btn1 = Button(window, text='Quit', command=lambda: quit(None))

window.mainloop()
tlentali
  • 3,407
  • 2
  • 14
  • 21
UnlinedBus
  • 13
  • 5
0

For menu bars:

def quit():
    root.destroy()

menubar = Menu(root)
filemenu = Menu(menubar, tearoff=0)

filemenu.add_separator()

filemenu.add_command(label="Exit", command=quit)
menubar.add_cascade(label="menubarname", menu=filemenu)
root.config(menu=menubar)
root.mainloop()
LenyaKap
  • 1
  • 2
0

I use below codes for the exit of Tkinter window:

from tkinter import*
root=Tk()
root.bind("<Escape>",lambda q:root.destroy())
root.mainloop()

or

from tkinter import*
root=Tk()
Button(root,text="exit",command=root.destroy).pack()
root.mainloop()

or

from tkinter import*
root=Tk()
Button(root,text="quit",command=quit).pack()
root.mainloop()

or

from tkinter import*
root=Tk()
Button(root,text="exit",command=exit).pack()
root.mainloop()
kourosh
  • 81
  • 1
  • 4
0

Code snippet below. I'm providing a small scenario.

import tkinter as tk
from tkinter import *

root = Tk()

def exit():
    if askokcancel("Quit", "Do you really want to quit?"):
        root.destroy()

menubar = Menu(root, background='#000099', foreground='white',
               activebackground='#004c99', activeforeground='white')

fileMenu = Menu(menubar,  tearoff=0, background="grey", foreground='black',
                activebackground='#004c99', activeforeground='white')
menubar.add_cascade(label='File', menu=fileMenu)

fileMenu.add_command(label='Exit', command=exit)

root.config(bg='#2A2C2B',menu=menubar)

if __name__ == '__main__':
    root.mainloop()

I have created a blank window here & add file menu option on the same window(root window), where I only add one option exit.

Then simply run mainloop for root.

Try to do it once

ChrisM
  • 505
  • 6
  • 18
Ozzius
  • 131
  • 2
  • 8
0

Of course you can assign the command to the button as follows, however, if you are making a UI, it is recommended to assign the same command to the "X" button:

def quit(self): # Your exit routine
   self.root.destroy()

self.root.protocol("WM_DELETE_WINDOW", self.quit) # Sets the command for the "X" button 

Button(text="Quit", command=self.quit) # No ()

Geetansh G
  • 17
  • 7
-1

There is a simple one-line answer:

Write - exit() in the command

That's it!

snookso
  • 377
  • 3
  • 16