Comment gérer l'événement de fermeture de la fenêtre (l'utilisateur clique sur le bouton 'X') dans un programme Python Tkinter?
Tkinter supporte un mécanisme appelé gestionnaires de protocole . Ici, le terme protocole fait référence à l'interaction entre l'application et le gestionnaire de fenêtres. Le protocole le plus couramment utilisé est appelé WM_DELETE_WINDOW
, et sert à définir ce qui se passe lorsque l'utilisateur ferme explicitement une fenêtre à l'aide du gestionnaire de fenêtres.
Vous pouvez utiliser la méthode protocol
pour installer un gestionnaire pour ce protocole (le widget doit être un Tk
ou Toplevel
widget):
Ici vous avez un exemple concret:
import tkinter as tk
from tkinter import messagebox
root = 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 a montré une modification classique du bouton de fermeture.
L’autre consiste à faire en sorte que le bouton de fermeture minimise la fenêtre.
Vous pouvez reproduire ce problème en utilisant la méthode iconify
soit le protocole deuxième argument de la méthode.
Voici un exemple de travail testé sur Windows 7:
# Python 3
import tkinter
import tkinter.scrolledtext as scrolledtext
class GUI(object):
def __init__(self):
root = self.root = tkinter.Tk()
root.title('Test')
# make the top right close button minimize (iconify) the main window
root.protocol("WM_DELETE_WINDOW", root.iconify)
# make Esc exit the program
root.bind('<Escape>', lambda e: root.destroy())
# create a menu bar with an Exit command
menubar = 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 attached
txt = scrolledtext.ScrolledText(root, undo=True)
txt['font'] = ('consolas', '12')
txt.pack(expand=True, fill='both')
gui = GUI()
gui.root.mainloop()
Dans cet exemple, nous donnons à l'utilisateur deux nouvelles options de sortie:
le menu Fichier classique -> Quitter, ainsi que le Esc bouton.
En fonction de l'activité de Tkinter, end esp. lorsque vous utilisez Tkinter.after, arrêter cette activité avec destroy()
, même en utilisant protocol (), un bouton, etc. - perturbera cette activité (erreur "en cours d'exécution") plutôt que de la terminer. La meilleure solution dans presque tous les cas consiste à utiliser un drapeau. Voici un exemple simple et stupide d'utilisation (bien que je sois certain que la plupart d'entre vous n'en ont pas besoin! :)
from Tkinter import *
def close_window():
global running
running = False
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()
Cela met fin à l'activité graphique bien. Il vous suffit de vérifier running
au bon endroit.
Essayez la version simple:
import tkinter
window = Tk()
closebutton = Button(window, text='X', command=window.destroy)
closebutton.pack()
window.mainloop()
Ou si vous souhaitez ajouter plus de commandes:
import tkinter
window = Tk()
def close():
window.destroy()
#More Functions
closebutton = Button(window, text='X', command=close)
closebutton.pack()
window.mainloop()