如何在Python Tkinter程序中处理窗口关闭事件(用户单击"X"按钮)?
Tkinter支持一种称为协议处理程序的机制.这里,术语协议指的是应用程序和窗口管理器之间的交互.调用最常用的协议WM_DELETE_WINDOW
,用于定义用户使用窗口管理器显式关闭窗口时发生的情况.
您可以使用该protocol
方法为此协议安装处理程序(小部件必须是小部件Tk
或Toplevel
小部件):
这里有一个具体的例子:
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展示了关闭按钮的一个经典修改.
另一种是使关闭按钮最小化窗口.
您可以通过将iconify方法
作为协议方法的第二个参数来重现此行为.
这是一个在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('', 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()
在此示例中,我们为用户提供了两个新的退出选项:
经典文件菜单 - >退出,以及Esc按钮.
取决于Tkinter活动,尤其是在使用Tkinter.after时,使用destroy()
-即使通过使用protocol(),按钮等来停止此活动,也会干扰此活动(“执行时出错”),而不仅仅是终止它。在几乎每种情况下,最好的解决方案是使用标志。这是一个简单,愚蠢的用法示例(尽管我敢肯定,你们大多数人都不需要它!
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()
这样可以很好地终止图形活动。您只需要running
在正确的位置检查即可。