“update”和“update_idletasks”有什么区别?

29

effbot.org 文档中,我们了解到关于 update 函数的以下内容:

处理所有挂起的事件,调用事件回调函数,完成任何挂起的几何管理,必要时重绘小部件,并调用所有挂起的空闲任务。应该谨慎使用此方法,因为如果从错误的位置调用(例如从事件回调内部调用或从可以从事件回调中以任何方式调用的函数中调用等),它可能会导致非常严重的竞态条件。当存在疑虑时,请改用 update_idletasks

另一方面,这是关于 update_idletasks 函数的内容:

调用所有待处理的空闲任务,而不处理任何其他事件。这可以用于执行几何管理和重绘小部件(如果需要),而不调用任何回调函数。 据我所知,“调用所有待处理的空闲任务”,“完成所有待处理的几何管理”和“根据需要重绘小部件”都是指update_idletasks。我唯一看到的区别是,update会“处理所有待处理的事件”并“调用事件回调函数”。我想这就是为什么我们不应该在事件回调中调用update的原因。 然而,我见过examples使用update_idletasks和update一起使用,我不明白原因,因为理论上update做了update_idletasks的所有事情。 文档中所说的“待处理事件”和“空闲任务”具体是什么?它们之间有什么区别和联系?
在什么情况下应该使用update而不是update_idletasks?具体示例也将受到赞赏。
1个回答

35
我唯一看到的区别是,update处理所有挂起的事件并调用事件回调函数。这就是为什么我们不应该在事件回调函数内调用update的原因,我想。
你说得对。挂起的事件是什么?主要是使用“after”调度的事件。正如你在问题中提到的,还有触发重绘的事件。
何时应该使用update而不是update_idletasks呢?几乎没有。老实说,我的实用答案是“除非调用update_idletasks不足以完成任务,否则永远不要调用update”。
重要的是要记住,update阻塞,直到所有事件都被处理。实际上,这意味着您有一个嵌套在另一个mainloop中的mainloop。在无限循环内部放置另一个无限循环从来都不是一个好主意。
如果你看到一个调用另一个的例子,那就是糟糕的例子。老实说,几乎没有任何理由这样做。我看到很多代码比它应该调用update更频繁。

1
我长期遵循这个建议。然而,我发现在10秒循环内关闭按钮无法正常工作。原因是必须将update_idletasks()更改为update(),然后按钮才能正常工作。同时,EscapeWM_DELETE也绑定到关闭函数上,但在使用.update()之前它们也无法正常工作。 - WinEunuuchs2Unix

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接