简体   繁体   English

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

[英]Message Box Dialog at Exit using Tkinter in Python

I want to show a message box dialog when pressing the "X" button to close the GUI.我想在按下“X”按钮关闭 GUI 时显示一个消息框对话框。 I want to ask the user if he's sure he wants to exit the program with a Yes/No choice.我想问用户他是否确定他想用是/否选择退出程序。 I'm getting an error when I press "Yes" in the dialog and the GUI closes if I press "NO".在对话框中按“是”时出现错误,如果按“否”则 GUI 关闭。 This is the full code 这是完整的代码

This is the error I'm getting:这是我得到的错误:

self.tk.call('destroy', self._w) self.tk.call('destroy', self._w)

_tkinter.TclError: can't invoke "destroy" command: application has been destroyed _tkinter.TclError:无法调用“destroy”命令:应用程序已被销毁

This is what I've done so far:这是我到目前为止所做的:

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)

You can use the protocol method to bind the window deletion with a function.您可以使用protocol方法将 window 删除与 function 绑定。

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()

UPDATE更新

According to the docs of atexit module根据atexit模块的文档

Functions thus registered are automatically executed upon normal interpreter termination.这样注册的函数会在解释器正常终止时自动执行。

The function registered was called after the mainloop was destroyed (since nothing proceeds, it marks the end of program).注册的mainloop在主循环被破坏后被调用(因为没有任何进展,它标志着程序的结束)。 The GUI element that the function tries to destroy doesn't exist anymore, as also stated by the error. function 试图破坏的 GUI 元素不再存在,如错误所述。

This module is not meant for the use case you trying to achieve, it's usually used for "cleanup" functions that are supposed to perform a task after the program terminates.该模块不适用于您尝试实现的用例,它通常用于应该在程序终止后执行任务的“清理”功能。

The callback registered via the WM_DELETE_WINDOW protocol gives you the control over what happens when the window is instructed to close.通过WM_DELETE_WINDOW协议注册的回调使您可以控制 window 被指示关闭时发生的情况。

Just to add to @AST's answer:只是添加到@AST的答案:

You are trying to use the atexit library to block closing the tkinter window when the program tries to exit.当程序尝试退出时,您正在尝试使用atexit库来阻止关闭 tkinter window。 The problem is that the atexit library calls your function after the window is destroyed.问题是atexit库在 window 被销毁后调用您的 function 。 I don't even think that you can block your program exiting using the atexit .我什至不认为您可以使用atexit阻止程序退出。 That is why @AST suggested using root.protocol("WM_DELETE_WINDOW", on_close) which runs when the tkinter window is trying to close (works only when the user presses the "X" button).这就是为什么@AST 建议使用在 tkinter window 试图关闭时运行的root.protocol("WM_DELETE_WINDOW", on_close) (仅在用户按下“X”按钮时有效)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM