【问题标题】:Why does tkinter.Tk.update() block while the window is being resized?为什么在调整窗口大小时 tkinter.Tk.update() 会阻塞?
【发布时间】:2019-10-20 12:59:36
【问题描述】:

我目前正在使用curio 并试图将tkinter 的回调转换为与异步代码兼容的东西。我已经弄清楚了大部分事情,事件等待,协议,但唯一剩下的就是窗口更新。

在调整窗口大小时,tkinter.Tk.update 方法会阻塞。这搞砸了我的异步代码,因为一切都必须在没有阻塞的情况下运行。我不能在另一个线程中运行它,就像this answer notes

这里有一些测试代码,用于计算调用 update() 需要多长时间。

import tkinter
from time import monotonic

window = tkinter.Tk()
try:
    while True:
        started = monotonic()
        window.update() # This is the blocking call
        delta = monotonic() - started
        if delta >= 0.5:
            print(f'{func.__name__} took {delta} seconds to run')

except tkinter.TclError:
    # The window is closed
    pass

您可以尝试调整窗口大小一秒钟,然后打印功能就会运行。如果你离开它,什么都不会发生。这意味着事件循环总是在处理来自调整大小的事件。

注意:在屏幕上移动鼠标不会触发它,尽管稍作修改以检查事件,<Motion> 事件的发生方式多于 <Configure> 事件。

我目前可以通过运行 tkinter.Tk.resizable(False, False) 来绕过此问题,以防止调整大小。我非常想在没有这种限制的情况下工作,我对调用阻塞的原因很感兴趣。也许有事件循环在内部处理事件,但我不确定。

【问题讨论】:

    标签: python tkinter


    【解决方案1】:

    为什么在调整窗口大小时 tkinter.Tk.update() 会阻塞?

    我认为答案是因为update 在返回之前必须处理事件队列中的所有事件,并且当您拖动窗口的边缘或角落时,调整窗口大小会向事件队列发送稳定的事件流.

    【讨论】:

    • 有没有办法在不阻塞循环的情况下单独获取这些事件?如果没有,我会保持它不可调整大小。谢谢:D
    • @GeeTransit:不,没有。
    猜你喜欢
    • 2011-04-24
    • 1970-01-01
    • 2019-06-17
    • 1970-01-01
    • 1970-01-01
    • 2019-05-15
    • 1970-01-01
    • 2017-08-04
    • 2012-08-02
    相关资源
    最近更新 更多