使用“wait_variable()”时无法退出 tkinter 应用程序

2024-01-16

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

我一直在尝试绑定"WM_DELETE_WINDOW"当我关闭窗口但无法实现该功能时,该事件会退出我的 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) to on_exit()(或者如果我在关闭窗口之前先单击了按钮)但是如果我尝试在不按按钮的情况下关闭窗口,则代码将不会退出。

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

I tried os._exit(1)它有效,但我认为它不干净。


正如您更新的问题指出的那样,问题是wait_variable()。取消此方法的文档wait_variable()进入不会中断的本地事件循环mainloop然而,在本地事件循环终止(变量以某种方式更新)之前,它似乎会阻止 python 实例终止,因为仍然存在活动循环。因此,为了防止这种情况,您还正确地指出您需要在终止 tk 实例之前更新此变量。

这可能看起来很奇怪,但这是我所期望的行为。据我了解,在 python 实例退出之前需要终止活动循环。

正如布莱恩在评论中指出的wait_variable()方法是“一个调用vwait http://tcl.tk/man/tcl8.5/TclCmd/vwait.htm嵌入式 tcl 解释器内的命令。这个 tcl 解释器对 python 异常一无所知,这可能就是它无法识别 sys.exit() 引发的 python 异常的原因”

相关文档链接:

等待变量() https://web.archive.org/web/20201112021403id_/https://effbot.org/tkinterbook/widget.htm#Tkinter.Widget.wait_variable-method

链接中的相关文字:

等待变量(名称)

等待给定的 Tkinter 变量 改变。该方法进入本地事件循环,因此该方法的其他部分 应用程序仍将响应。本地事件循环是 当变量更新时终止(将其设置为当前值) 价值也很重要)。

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

这条线应该适合你:

submitted.set(submitted.get())

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

您的新函数应如下所示:

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用“wait_variable()”时无法退出 tkinter 应用程序 的相关文章

随机推荐