2

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

from tkinter import *

root1 = Tk()
root2 = Tk()

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

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

感谢:D

4

2 回答 2

1

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

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


像你所做的那样做两次调用tkinter.Tk()是创建两个独立的底层 Tcl/Tk 环境(技术术语是“解释器”,即使它有一个字节码编译器等等)共享一个线程。由于 Tcl 使用的安全模型非常不同,从 Tcl/Tk 的角度来看,这是明智的,但从 Python 的角度来看,这几乎是一派胡言。效果在操作上是可以描述的,但更广泛地理解它们是非常困难的,建议你不要尝试。

于 2021-08-15T19:12:24.583 回答
0

我不能真正深入地回答这个问题,但给出一些指示:

.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)

我认为这段代码应该只处理与 root1 相关的事件

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

于 2021-08-15T17:42:53.167 回答