`new_root.mainloop()` 不会使 main window 无响应
`new_root.mainloop()` doesn't make main window unresponsive
假设我有这个 tkinter 脚本:
import tkinter as tk
def callback():
new_root = tk.Tk()
new_root.mainloop()
print("Done")
root = tk.Tk()
button = tk.Button(root, text="Click me", command=callback)
button.pack()
root.mainloop()
根据我对 tkinter 的理解,当我按下按钮时,应该创建一个新的 window 和 tcl 解释器。虽然 运行 callback
,但主 window (root
) 不应更新,因此它应该没有响应。 new_root.mainloop()
是一个 while True
循环,一直运行到第二个 window 关闭。因此,当我按下按钮时,它应该创建一个新的 window,在其上调用 .mainloop()
,这应该会使主 window 无响应。问题是那不会发生。即使代码执行卡在 new_root.mainloop()
.
中,主要的 window 也是响应式的
同时关闭第二个 window 不会打印 "Done"
直到其余的 tkinter windows 关闭。为什么会这样?
我查看了 tkinter
和 _tkinter
的源代码,但找不到任何有用的东西。我有 Python 3.7.9,tcl 8.6
虽然您是 运行 一个辅助事件循环(真的不要那样做!)它仍然与外部循环共享相同的事件处理程序注册表,因此进入的事件在内部处理循环就像在外部一样。 (有一段常见的低级事件处理代码深入到 OS 以有效地进行事件处理。该代码,即通知程序,非常 很少见人们应该接触;这很棘手,因为它合并了一些非常奇怪和不同的事件源,同时还解决了一些平台上的一堆奇怪的错误。)event_loop
方法 returns once all windows 被删除。它从字面上调用带有适当标志的低级事件处理引擎(API 调用是 Tcl_DoOneEvent()
),并在 while 循环中执行(直到现有 windows 的数量低于 1; 正是它在等什么)。这就是为什么您可能不应该指望它终止并且绝对不应该将它嵌套在 GUI 回调中。
假设我有这个 tkinter 脚本:
import tkinter as tk
def callback():
new_root = tk.Tk()
new_root.mainloop()
print("Done")
root = tk.Tk()
button = tk.Button(root, text="Click me", command=callback)
button.pack()
root.mainloop()
根据我对 tkinter 的理解,当我按下按钮时,应该创建一个新的 window 和 tcl 解释器。虽然 运行 callback
,但主 window (root
) 不应更新,因此它应该没有响应。 new_root.mainloop()
是一个 while True
循环,一直运行到第二个 window 关闭。因此,当我按下按钮时,它应该创建一个新的 window,在其上调用 .mainloop()
,这应该会使主 window 无响应。问题是那不会发生。即使代码执行卡在 new_root.mainloop()
.
同时关闭第二个 window 不会打印 "Done"
直到其余的 tkinter windows 关闭。为什么会这样?
我查看了 tkinter
和 _tkinter
的源代码,但找不到任何有用的东西。我有 Python 3.7.9,tcl 8.6
虽然您是 运行 一个辅助事件循环(真的不要那样做!)它仍然与外部循环共享相同的事件处理程序注册表,因此进入的事件在内部处理循环就像在外部一样。 (有一段常见的低级事件处理代码深入到 OS 以有效地进行事件处理。该代码,即通知程序,非常 很少见人们应该接触;这很棘手,因为它合并了一些非常奇怪和不同的事件源,同时还解决了一些平台上的一堆奇怪的错误。)event_loop
方法 returns once all windows 被删除。它从字面上调用带有适当标志的低级事件处理引擎(API 调用是 Tcl_DoOneEvent()
),并在 while 循环中执行(直到现有 windows 的数量低于 1; 正是它在等什么)。这就是为什么您可能不应该指望它终止并且绝对不应该将它嵌套在 GUI 回调中。