`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 回调中。