更好地理解 mainloop()

Understanding mainloop() better

我对tk.mainloop()的理解是它将运行处理与第一个创建的Tcl解释器相关的window事件,而<widget>.mainloop()将处理window的事件window 与与小部件链接的解释器相关。然后我遇到了这段代码:

from tkinter import *

root1 = Tk()
root2 = Tk()

root1.mainloop() # Shouldn't this just handle the events of the first window

根据我的理解,我认为这段代码应该只处理与 root1 相关的事件,但是 root2 也会出现并且它也是响应式的(这意味着它的事件也是正在处理..?)。如果我对 mainloop() 工作原理的理解有误,请纠正我。

谢谢 :D

我真的无法深入回答这个问题,但提供一些指示:

.mainloop()无非是IDE的死锁。我可以证明这一点:

import tkinter as tk

def info():
    print('here')
    root1.quit()

root1 = tk.Tk()
root2 = tk.Tk()
b = tk.Button(root1, text='Quit',command=info)
b.pack()
b2 = tk.Button(root2,text='dest',command=info)
b2.pack()

root1.mainloop()
root2.mainloop()
root1.mainloop()
exit(0)

I thought this code was supposed to handle just the events related to root1

Windows需要注册到操作系统的Windowmanager,事件由Windowmanager发送或接收。

mainloop()方法在当前线程上运行事件处理循环,直到allwindows开始的线程已经关闭或者quit() 方法被调用(它在内部设置一个由核心事件循环运行器检查的标志)。它阻塞线程,除了它会根据需要执行所有已注册的回调。 底层机制实际上并不与任何特定的 window 相关联,而是与线程相关联。 只是 Tkinter 不喜欢将事物映射为自由函数,尽管这确实是什么他们是。

强烈建议您不要同时激活对 tkinter.Tk() 的两次调用的结果。它有效,但结果可能非常混乱。如果您同时从多个线程执行它,它会变得更加混乱(这应该可以工作——除了在 macOS 上出于混乱的原因——但结果往往令人费解)。 (这不适用于 tkinter.Tcl() 确实 在多次完成并从多个线程中合理工作。它产生的对象是线程绑定的,但是有很多实例是明智的,你可以在它们自己的线程中或一起拥有这些实例。)


像你所做的那样对 tkinter.Tk() 进行两次调用是创建两个独立的底层 Tcl/Tk 环境(技术术语是“解释器”,尽管它有一个字节码编译器等on) 共享线程。由于 Tcl 使用的安全模型非常不同,从 Tcl/Tk 的角度来看这是明智的,但从 Python 的角度来看这几乎完全是无稽之谈。这些影响在操作上可以描述为小规模的,但要更广泛地理解它们是非常困难的,建议您不要尝试。