python - 使用 "wait_variable()"时无法退出 tkinter 应用程序

标签 python python-3.x tkinter

我有一个 python 代码,其中包括 tkinter 窗口和其他正在运行的任务。

我一直在尝试将 "WM_DELETE_WINDOW" 事件绑定(bind)到一个函数,该函数在我关闭窗口但无法实现时退出我的 python 代码。

这是我的尝试:

def on_exit():
    root.destroy()
    sys.exit()
root.protocol('WM_DELETE_WINDOW', on_exit)

窗口被成功销毁,但python代码没有退出。 sys.exit() 不工作的任何可能原因?

我做错了什么?我应该尝试任何替代方法吗?

通过一些测试,我发现了问题所在。

这是一个总结我的代码的小代码,它要大得多。

import tkinter as tk
import sys

root = tk.Tk()
submitted = tk.IntVar()

def on_exit():
    root.destroy()
    sys.exit()
root.protocol('WM_DELETE_WINDOW', on_exit)

def submit():
    submitted.set(1)
    print("submitted")

button= tk.Button(root, text="Submit",command=submit)
button.pack()
button.wait_variable(submitted)

root.mainloop()

我现在相信 wait_variable 是问题的根源。

当我将 submitted.set(1) 添加到 on_exit() 时(或者如果我在关闭窗口之前先单击按钮),代码实际上退出了,但是如果我尝试在不按下按钮的情况下关闭窗口,代码不会退出。

那么这是否意味着 wait_variable 不仅让 tkinter 应用程序等待,而且还阻止 python 代码退出?!

我尝试了 os._exit(1) 并且它有效,但我认为它不干净。

最佳答案

正如您更新后的问题所指出的,问题出在wait_variable()。关闭此方法的文档 wait_variable() 进入一个不会中断 mainloop 的本地事件循环,但是看起来直到该本地事件循环终止(变量被更新以某种方式)它将阻止 python 实例终止,因为仍然有一个事件循环。因此,为了防止这种情况,您还正确地指出您需要在终止 tk 实例之前立即更新此变量。

这可能有点奇怪,但这是我所期望的行为。据我了解,在 python 实例退出之前需要终止事件循环。

正如 Bryan 在评论中指出的那样,wait_variable() 方法是“一个在嵌入式 tcl 解释器中调用 vwait 命令的函数。这个 tcl 解释器对 python 异常一无所知,它是可能是为什么它无法识别 sys.exit() 引发的 python 异常”

相关文档链接:

wait_variable()

来自链接的相关文本:

wait_variable(name)

Waits for the given Tkinter variable to change. This method enters a local event loop, so other parts of the application will still be responsive. The local event loop is terminated when the variable is updated (setting it to it’s current value also counts).

您还可以将变量设置为当前设置的任何值以终止此事件循环。

这一行应该适合你:

submitted.set(submitted.get())

也就是说你实际上并不需要 sys.exit()。您可以简单地使用 root.destroy()

你的新函数应该是这样的:

def on_exit():
    submitted.set(submitted.get())
    root.destroy()

如果主循环之后没有更多代码,python 实例将自动关闭。

关于python - 使用 "wait_variable()"时无法退出 tkinter 应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56175296/

相关文章:

python - 我终于理解了递归还是我错得离谱?

python - 将变量(非模型字段)传递给 Django Rest 框架中的序列化器

python-3.x - selenium.common.exceptions.ElementNotInteractableException : Message: element not interactable when clicking on an element using Selenium Python

python - 如何选择列表框中的多个项目?

Python,Pyinstaller 在 Windows 中创建快捷方式

Python 文本文件到 xml

python - 类型错误 : at/ 'module' object is not callable

python - 使用 Python 将视频转换为单独的帧而不使用 ffmpeg?

python - 如何将滚动条附加到 tkinter 中的下拉列表?

python - 用python解析xpath