Tkinter:检查根是不是已被破坏?

Posted

技术标签:

【中文标题】Tkinter:检查根是不是已被破坏?【英文标题】:Tkinter: Check if root has been destroyed?Tkinter:检查根是否已被破坏? 【发布时间】:2013-12-01 02:09:57 【问题描述】:

我正在使用 Tkinter 和线程编写一个应用程序。

我遇到的问题是,关闭主应用程序后,一些线程仍在运行,我需要一种方法来检查根窗口是否已被破坏以避免TclError: can't invoke "wm" command

我知道的所有方法:wminfo_exists()state() 在根被销毁后都会返回错误。

【问题讨论】:

似乎您可以在 wminfo_exists() 调用周围放置一个 try/except 并假设任何 TclError 意味着根不再存在。 【参考方案1】:

我会为此添加我的解决方法,以防有人遇到同样的问题。我遵循了here 的建议。我拦截了窗口的关闭事件以设置标记root 的标志已经失效,并在需要时检查该标志。

exitFlag = False

def thread_method():
    global root, exitFlag
    if not exitFlag:
        // execute the code relate to root

def on_quit():
    global exitFlag
    exitFlag = True
    root.destroy()

root.protocol("WM_DELETE_WINDOW", on_quit)

【讨论】:

【参考方案2】:

如果你正在使用这样的东西:

import Tkinter

root = Tkinter.Tk()
root.bind('<space>', lambda e: root.quit())  # quitting by pressing spacebar
root.mainloop()

而不是:root.destroy() 然后退出方法将杀死 Tcl 解释器,而不仅仅是从主循环中中断并删除所有小部件。所以一旦你打电话给root.quit(),你就可以肯定,你的root 完全死了!

您建议的所有其他方法(例如:wminfo_exists())仅在至少存在一个有效的Tk 时可用。


注意:

如果你使用多个主循环,你应该使用 destroy 方法来确保你的 ma​​in 主循环不会被杀死——但我不这么认为是你的情况。

【讨论】:

感谢您的回答。我遇到的问题是,在root.quit() 之后我仍然有一些线程在运行,我需要让我的线程知道root 已经死了。现在我必须解决拦截退出方法并设置一个全局变量让我的线程知道root 已经死了。我想知道是否还有其他解决方案。 root.winfo_exists()(没有'm')?无论如何,您为什么不使用 try/except 捕获该错误,而当它发生时您只需杀死您的线程? 我在关注discussion about thread,他们提到,在执行期间杀死线程是不好的做法。这就是为什么我希望找到一个解决方案,让我的程序的执行“和平地”结束。

以上是关于Tkinter:检查根是不是已被破坏?的主要内容,如果未能解决你的问题,请参考以下文章

在单独的线程中运行 Tkinter 表单

Tkinter GUI 未显示,但功能收到响应

pythy标准库之Tkinter(hello world窗口显示)

为啥 tkinter 不能很好地处理多处理?

Python连载60-Tkinter布局按钮以及属性详解

公司outlook邮箱附件老打不开,显示文件已被破坏或粉碎