Python中使用Tkinter创建退出时的消息框对话框

4
我想在关闭GUI的“X”按钮时显示一个消息对话框,询问用户是否确定退出程序并提供Yes/No选择。但当我按“Yes”时,会出现错误,如果我按“NO”,则GUI将关闭。这是完整代码
我得到的错误是:self.tk.call('destroy', self._w)。
_tkinter.TclError: 无法调用“destroy”命令:应用程序已被销毁。
到目前为止,我所做的事情是:
import atexit

def deleteme():
     result = messagebox.askquestion("Exit", "Are You Sure You Want to Exit?")
     if result == "yes":
        root.destroy()
     else:
        return None

atexit.register(deleteme)

你遇到了什么错误?能否请提供完整的回溯信息。如果我猜的话,可能是因为root未定义。 - TheLizzard
请发布完整的代码和错误代码。 - Delrius Euphoria
我已发布完整代码和我遇到的错误,谢谢! - Georges Elkassouf
基本上它告诉你那个窗口已经关闭了。你不能关闭一个已经关闭的窗口。你的一段代码在该函数被调用之前销毁了该窗口。 - TheLizzard
2个回答

5
你可以使用 protocol 方法将窗口删除操作与一个函数绑定。
from tkinter import *
from tkinter import messagebox

def on_close():
    response=messagebox.askyesno('Exit','Are you sure you want to exit?')
    if response:
        root.destroy()

root=Tk()
root.protocol('WM_DELETE_WINDOW',on_close)

root.mainloop()

更新

根据atexit模块的文档:

因此注册的函数将在解释器正常终止时自动执行。

注册的函数在mainloop被销毁后被调用(由于程序已经结束,它标志着程序的结束)。该函数试图销毁的GUI元素已不存在,这也是报错信息所陈述的。

该模块并不适合你所尝试实现的用例,通常用于“清理”函数,在程序结束后执行任务。

通过WM_DELETE_WINDOW协议注册的回调函数使您控制窗口关闭时会发生什么。


下次请解释为什么OP的方法不起作用。但对于正确答案仍然点赞。 - TheLizzard
1
@TheLizzard 不好意思,我完全忘记了,看起来你已经做过了,谢谢。为了完整起见,我已经更新了我的答案并附上了解释。 - astqx

3

只是为了补充@AST的回答:

你试图使用atexit库来阻止程序在退出时关闭tkinter窗口。问题在于atexit库在窗口被销毁后调用你的函数。我甚至认为您不能使用atexit来阻止程序退出。这就是为什么@AST建议使用root.protocol("WM_DELETE_WINDOW", on_close),它在tkinter窗口尝试关闭时运行(仅在用户按下“X”按钮时起作用)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接