使用“wait_variable()"时无法退出 tkinter 应用程序; [英] Unable to exit tkinter app when using "wait_variable()"

查看:21
本文介绍了使用“wait_variable()"时无法退出 tkinter 应用程序;的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含 tkinter 窗口和其他运行任务的 Python 代码.

I have a python code that includes tkinter window and other running tasks.

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

I've been trying to bind "WM_DELETE_WINDOW" event to a function that exits my python code when I close the window but can't achieve that.

这是我的尝试:

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

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

The window is destroyed successfully but the python code doesn't exit. Any possible reason for sys.exit() not to work?

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

What am I doing wrong? any alternative approach should I try?

做了一些测试,我发现了问题所在.

Doing some testing I figured out what can be the problem.

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

Here's a small code that summarizes my code which is much bigger.

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 是问题的根源.

I believe now that wait_variable is the source of the problem.

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

And the code actually exits when I added submitted.set(1) to on_exit() ( or if I clicked the button first before closing the window ) but if I tried closing the window without pressing the button, the code won't exit.

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

So does this mean that wait_variable not only makes tkinter app wait, but also prevents python code exiting?!

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

I tried os._exit(1) and it worked, but I think it's not clean.

推荐答案

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

As your updated question points out the problem is wait_variable(). Going off the documentation for this method wait_variable() enters a local event loop that wont interrupt the mainloop however it appears that until that local event loop is terminated (the variable is updated in some way) it will prevent the python instance from terminating as there is still an active loop. So in order to prevent this you have also correctly pointed out you need to update this variable right before you terminate the tk instance.

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

This might seam odd but it is the behavior I would expect. It is my understanding that an active loop needs to be terminated before a python instance can exit.

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

As Bryan has pointed out in the comments the wait_variable() method is "a function which calls the vwait command inside the embedded tcl interpreter. This tcl interpreter knows nothing about python exceptions which is likely why it doesn't recognize the python exception raised by sys.exit()"

相关文档链接:

wait_variable()

来自链接的相关文本:

wait_variable(name)

wait_variable(name)

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

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

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

You can also set the variable to whatever it is currently set as to terminate this event loop.

这条线应该适合你:

submitted.set(submitted.get())

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

That said you do not actually need sys.exit(). You can simply use root.destroy().

您的新函数应如下所示:

You new function should look like this:

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

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

The python instance will automatically close if there is no more code after the mainloop.

这篇关于使用“wait_variable()"时无法退出 tkinter 应用程序;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆