当我的Tkinter应用程序结束时,它必须做一些工作(例如将一些数据存储到文件中)。在某些情况下,应询问用户是否确实要关闭该应用程序。
有多种方法可以关闭Tkinter应用程序:
我怎样才能抓住所有这类“事件”?
#!/usr/bin/env python3
from tkinter import *
def on_delete_window():
print('on_delete_window')
print('save my data')
if __name__ == '__main__':
root = Tk()
Button(root, text='Destroy', command=root.destroy).pack()
Button(root, text='Quit', command=root.quit).pack()
menu = Menu(root)
menu.add_command(label='Destroy', command=root.destroy)
menu.add_command(label='Quit', command=root.quit)
root.config(menu=menu)
# this catches ONLY the X in the window
# but none of the two buttons!
root.protocol('WM_DELETE_WINDOW', on_delete_window)
root.mainloop()
答案 0 :(得分:2)
如果要在一次调用中捕获所有内容,请绑定到根窗口的<Destroy>
事件。无论它如何被破坏,你的函数都会被调用。但要小心 - 每个小部件都会捕获绑定到根窗口的事件。只有当它是被销毁的根窗口时,您才会想要做最后的操作。
如果您想询问用户是否确定他们何时通过窗口管理器关闭窗口,您需要将功能绑定到WM_DELETE_WINDOW
协议,就像您一样。如果您想询问他们是否确定从按钮或菜单退出时,您必须将对话框添加到这些小部件调用的任何功能中。
请注意<Destroy>
上的绑定只有在窗口被销毁后才会发生,此时要求确认将为时已晚。您可以将代码置于destroy函数中自动保存,但是您必须在应用程序被销毁之前将确认放在一个被调用的函数中。
import tkinter as tk
def on_destroy(event):
if event.widget.winfo_parent() == "":
print("program is exiting...")
root = tk.Tk()
label = tk.Label(root, text="Hello, world")
label.pack(fill="both", padx=20, pady=20)
root.bind("<Destroy>", on_destroy)
root.mainloop()
答案 1 :(得分:2)
一种解决方法是定义一个closing_procedure
方法,该方法接受callback
参数,该参数根据对messagebox
对话框的回复进行/关闭回调,您将重定向到该对话框例如,所有结账操作。
try: # In order to be able to import tkinter for
import tkinter as tk # either in python 2 or in python 3
import tkinter.messagebox as tkmb
except ImportError:
import Tkinter as tk
import tkMessageBox as tkmb
def closing_procedure(callback, *args, **kwargs):
response = tkmb.askyesno("Quit", "Do you really want to close?")
if response:
callback(*args, **kwargs)
else:
print("Closing cancelled!")
if __name__ == '__main__':
root = tk.Tk()
button = tk.Button(root, text="Quit",
command=lambda : closing_procedure(root.quit))
button.pack()
root.protocol('WM_DELETE_WINDOW',
lambda : closing_procedure(root.destroy))
root.mainloop()