我在这个网站上看到了很多问题,人们会问如何在tkinter sudo umount /mnt/c
sudo mount -t drvfs C: /mnt/c -o metadata
中执行用户编写的代码,例如函数foo
,例如this或this。存在两种选择:使用mainloop
方法,或使用线程。我想更多地了解after
方法实际上是如何工作的。
更确切地说,受到这个excellent article的启发,我们想要了解更多关于Python中GIL如何工作的高级描述,我想知道更多after
方法的工作原理就tkinter after
中的Python解释器处理foo
而言
当我使用mainloop
插入代码时,我特别困惑CPython解释器如何逐步完成代码。如何after
最终由tkinter foo
执行?
到目前为止我发现了:
Bryan Oakley引用第一个链接说:"之后没有创建另一个执行线程。 Tkinter是单线程的。之后只是将一个函数添加到队列中。"
但检查源代码
mainloop
并没有真正帮助我,因为它没有透露这些问题的答案,而且我是新手程序员,所以我真的不明白如何进一步追踪这一点。
答案 0 :(得分:0)
我想更多地了解after方法是如何实际运作的。
mainloop
只是一个无限循环,它扫描一些内部队列以查看是否有任何要处理的事件。可以把它想象成是这样实现的:
def mainloop():
while the_window_exists():
if len(after_queue) > 0:
event = after_queue.pop()
if event.time_to_execute >= time.time():
event.command(**event.args)
if len(event_queue) > 0:
...
它并没有按字面意思实现 - 它的效率更高一些,而且还有更多的功能,但逻辑上它几乎完全相同。
当你致电after
时,它只会在“后”队列上放置一些东西。没有更多,没有更少。
使用相同的类比,after
可能会实现如下:
def after(delay, code_to_run, *args):
event = Event()
event.code_to_run = code_to_run
event.args = args
event.time_to_execute = time.time() + delay
event_queue.append(event)
这就是它的全部。当您致电after
时,您正在将某些内容放入队列中,而mainloop
会将该内容从该队列中删除。这一切都发生在同一个线程中。
至mainloop
,您使用after
添加的功能与移动鼠标或按下按钮时添加的功能没什么不同 - 它只是队列中的事件对象。