【问题标题】:Which code does the mainloop() processes infinitely until any event occurs?mainloop() 会无限处理哪些代码,直到发生任何事件?
【发布时间】:2022-01-17 15:42:54
【问题描述】:

要理解我的问题,请遵循以下段落:

主循环无限处理什么代码?就像它一遍遍地读取整个程序的代码? 考虑代码:

from tkinter import *

window = Tk()
print("lol")
print("Hello World")
window.mainloop()

输出没有无限次打印“Hello World”或“lol”,因此 mainloop() 不会循环当前模块的代码。

现在考虑这段代码:

from tkinter import *
print("lol")
window = Tk()
print("Hello World")
while True:
    window.update()

现在,即使这段代码执行相同的输出,所以现在我们可以考虑 mainloop() 循环代码“window.update()”无限次,但效率更高(不知何故)。

现在第一个问题出现了 window.update() 函数做什么来更新 GUI 中的值,它是否再次从上到下重新读取代码,或者更新函数如何更新 GUI 小部件值.

第二个问题是:

我读过this article

“Python Tkinter 中的 Mainloop 是应用程序窗口的无限循环,它永远运行,因此我们可以看到静止的屏幕。 应用程序窗口就像一个框架,每微秒都在销毁,但主循环继续创建一个新的更新窗口。 破坏旧窗纱并创建新窗纱的过程发生得如此之快,以至于人眼甚至都没有意识到。 由于进程运行无限时间,这就是为什么我们能够看到我们面前的应用程序,当我们关闭窗口时,循环终止或退出。”

如果这是真的,那么要重新创建一个更新的窗口,root.mainloop() 必须一次又一次地完全读取整个根 GUI 代码,或者是否有其他解释。

在过去的 6 小时里,我一直在努力理解这一点,并且我访问了每个站点,但我找不到适合我生活的解决方案。

问候, 拉希克

【问题讨论】:

  • 它将代码包装在已编译的 DLL 中。您也不必担心它是如何工作的。这不会帮助您解决您自己的程序的任何问题。网络上的文章可能会使用隐喻来帮助您理解,但它们可能不是准确的描述。

标签: python tkinter


【解决方案1】:

主循环无限处理什么代码?是不是一遍一遍的读取整个程序的代码?

没有。

通过this function,它调用this C code,让嵌入式Tcl解释器处理一个事件,或者在尝试处理另一个事件之前等待Tkinter_busywaitinterval

现在,即使这段代码执行相同的输出,所以现在我们可以考虑 mainloop() 循环代码“window.update()”无限次,但效率更高(不知何故)。

window.update() 调用TCL update,描述为

[...] 通过反复进入事件循环直到处理完所有未决事件(包括空闲回调),使应用程序“更新”。

你的无限循环没有睡眠,所以它尽可能地旋转你的 CPU,几乎什么都不做。

[...] 是否再次从上到下重新读取代码,或者更新函数如何更新 GUI 小部件值。

它当然不会重新读取您的代码。它处理任何挂起的小部件更新,这可能是通过运行例如发生的。 window.text("...") 例如点击回调或.after() 超时等

我读了这篇文章 [...]

那篇文章似乎是错误的和/或至少过度简化了事情。

这个简单的示例时钟应该阐明事情是如何工作的:

import time
import tkinter as tk

root = tk.Tk()
text = tk.Label(root)
text.pack()

def tick():
    text["text"] = time.ctime()  # update `text` widget's content
    root.after(1000, tick)  # schedule for this function to be called after 1 second


if __name__ == '__main__':
    tick()  # call the `tick` function once before entering main loop
    root.mainloop()

【讨论】:

  • 在时钟示例中,程序是否曾经到达过 mainloop(),因为它应该无限调用 tick() 函数,或者 .after() 的行为类似于不同的线程?
  • 另外,进入事件循环如何重复更新未决事件?
  • (1) 仅安排稍后发生的事件。它不会阻塞。因此,勾号只是返回。 (2) 因为这就是它的编程目的;上面链接了实现。
猜你喜欢
  • 2011-04-10
  • 1970-01-01
  • 2018-01-29
  • 1970-01-01
  • 1970-01-01
  • 2015-02-13
  • 2014-06-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多