添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

root.destroy()和root.quit()之间有什么区别?

41 人关注

在Python中使用 tkinter ,关闭根窗口时, root.destroy() root.quit() 有什么区别?

一个比另一个更受欢迎吗?一个人是否释放了另一个人所没有的资源?

python
tkinter
Gary Willoughby
Gary Willoughby
发布于 2010-02-22
4 个回答
Bryan Oakley
Bryan Oakley
发布于 2020-04-25
已采纳
0 人赞同

root.quit() 导致mainloop退出。解释器仍然是完整的,所有的部件也是如此。如果你调用这个函数,你可以有在调用 root.mainloop() 后执行的代码,并且该代码可以与部件进行交互(例如,从一个入口部件获取一个值)。

调用 root.destroy() 将销毁所有的widget并退出mainloop。调用 root.mainloop() 后的任何代码都将运行,但任何试图访问任何部件(例如,从一个入口部件获取一个值)的尝试都将失败,因为该部件不再存在。

但是,如果我们有多个 Tk() 的实例,并且我们在其中一个实例上使用 root.destroy() ,这是否可以使我们避免使用多个 Tk() 实例的弊端,因为其中一个解释器被破坏了,我们只剩下一个实例?
@CoolCloud 你不应该有多个 Tk() 的实例,你需要用多个窗口做的任何事情都可以而且应该用 Toplevel() 来完成。
@Mike-SMT 本质上是的,但如果你能适当地多管理一个 Tk() ,也是无妨的。
@CoolCloud 在有可能管理多个实例的地方,这不是一个好主意,特别是对于初学者。当你问你的问题时,它意味着一个人可以不时地遇到这个问题,但一个初学者,在一般情况下,甚至应该避免这样做。如果你知道你在做什么,并且清楚地了解,如果你想的话,就去做吧,但是大部分(如果不是大部分)阅读你评论的人不应该认为使用Tk的多个实例是可以的。"技术上 "你可以,但可能不应该。有一些简单的方法可以将Tk的多个实例搞乱。
ErikT
ErikT
发布于 2020-04-25
0 人赞同

quit() 停止TCL解释器。这在大多数情况下是你想要的,因为你的Tkinter-app也会停止。idle本身就是一个Tkinker应用程序,所以如果你在你的应用程序中调用 quit() ,TCL解释器被终止,idle也会被终止(或者被混淆),这可能是一个问题。

替换代码2】只是终止了主循环,并删除了所有部件。因此,如果你从另一个Tkinter应用程序中调用你的应用程序,或者如果你有多个主循环,它似乎更安全。"

取自 http://www.daniweb.com/forums/thread66698.html

这个答案并不完全正确。 root.quit() 并没有 "停止TCL解释器"。它只是导致 mainloop 退出。解释器仍然是完整的,所有的部件也是如此。调用 root.destroy() 将破坏所有的部件 exit mainloop .
Dave Rove
Dave Rove
发布于 2020-04-25
0 人赞同

tkinter.Tk的 "quit "方法退出了 "mainloop "事件处理程序,而 "destroy "则销毁了所有嵌入的小部件,只有 then 退出 "主循环"。那么,"摧毁 "是两者中更好的吗?嗯,有时不是。如果 "destroy "由于某种原因不能销毁所有的部件,那么 "mainloop "就不会被退出,Python 就会被锁定。最好是让 Python 在脚本结束时有秩序地关闭东西。

例如,如果你在一个 Tkinter 窗口中嵌入一个 Matplotlib 绘图,这很有用,因为 Matplotlib 自己的部件使用起来有点笨重。不幸的是,如果你试图通过点击标题栏中常见的 "X "来关闭这个窗口,窗口会正常关闭,但Python会继续运行。如果这个脚本是从终端启动的,你必须按Ctrl-C键几分钟后才能回到提示符。原因是关闭窗口的事件被绑定到 "destroy "上,这并没有销毁Matplotlib对象,而是让它们成为了孤儿。

解决的办法是将关闭窗口的事件绑定到 "退出 "上。但是......如果脚本是在一个基于Tkinter的IDE中启动的,比如IDLE,那么就会产生一个新的问题,即窗口不会关闭,因为IDLE保持着Tkinter的运行。所以现在必须在mainloop之后加上 "destroy"。最后,一切都好了。

下面是一个Matplotlib绘图的最小例子,按一下Tkinter按钮就可以反转。它的窗口可以顺利关闭。但是如果窗口关闭事件被绑定到 "destroy "而不是 "quit",那么一个被锁定的Python进程就会保留下来。

#!/usr/bin/env python3
import tkinter as tk
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import matplotlib.pyplot as plt
root = tk.Tk()
data, = plt.plot([0,5,3,4,-5,3])
canvas = FigureCanvasTkAgg(plt.gcf(), master=root)
invert = lambda: (data.set_ydata(-data.get_ydata()), canvas.draw())
tk.Button(master=root, text="Invert", command=invert).pack()
canvas.get_tk_widget().pack(fill=tk.BOTH, expand=1)
root.protocol("WM_DELETE_WINDOW", root.quit)
root.mainloop()
root.destroy()

编辑:我补充一下,通过将窗口关闭事件绑定到both方法,你可以避免在 "mainloop "之后添加一行,如果因为某些原因需要这样做的话。

root.protocol("WM_DELETE_WINDOW", lambda: (root.quit(), root.destroy()))
    
Rupert
Rupert
发布于 2020-04-25
0 人赞同

My experience with root.quit() and root.destroy() ...

我有一个dos python脚本,它调用一个 tkinter 脚本(从combobox的一组已知值中选择),然后返回到dos脚本来完成其他事情。

我把TKinter脚本加到了父脚本上。我可能会把所有的都转换为tkinter,但目前来说,一个组合可以工作。它的工作方式如下。

为了在实施选择后摆脱窗口框,我需要
1) root.quit() 回调中的 我的所有按键都在那里被处理。