tkinters mainloop困住了我的foo

时间:2018-02-17 12:19:49

标签: python tkinter interpreter

我在这个网站上看到了很多问题,人们会问如何在tkinter sudo umount /mnt/c sudo mount -t drvfs C: /mnt/c -o metadata 中执行用户编写的代码,例如函数foo,例如thisthis。存在两种选择:使用mainloop方法,或使用线程。我想更多地了解after方法实际上是如何工作的。

更确切地说,受到这个excellent article的启发,我们想要了解更多关于Python中GIL如何工作的高级描述,我想知道更多after方法的工作原理就tkinter after中的Python解释器处理foo而言 当我使用mainloop插入代码时,我特别困惑CPython解释器如何逐步完成代码。如何after最终由tkinter foo执行?

到目前为止我发现了:

Bryan Oakley引用第一个链接说:"之后没有创建另一个执行线程。 Tkinter是单线程的。之后只是将一个函数添加到队列中。"

但检查源代码

mainloop

并没有真正帮助我,因为它没有透露这些问题的答案,而且我是新手程序员,所以我真的不明白如何进一步追踪这一点。

1 个答案:

答案 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添加的功能与移动鼠标或按下按钮时添加的功能没什么不同 - 它只是队列中的事件对象。