tkinter ScrolledText 在有睡眠命令时等待循环停止,但在没有睡眠命令时实时更新



我正在尝试将实时stdoutstderr输出到ScrolledText小部件。我已经得到了很好的实时输出,但ScrolledText小部件直到脚本最终执行后才更新。我在一个更简单的例子中测试了这一点,看看它是否是stdout行之间的时间。在将文本插入ScrollText小部件之前,我插入一个time.sleep(1)调用。有人能向我解释一下为什么ScrolledText小部件在每次调用scroll_object.insert(tk.INSERT,string)后都不更新吗?

import tkinter as tk
from tkinter.scrolledtext import ScrolledText
import time
def insert_stuff(scroll_object):
for i in range(10):
time.sleep(1)
string = f'{i}n'
scroll_object.insert(tk.INSERT,string)

root = tk.Tk()
output = ScrolledText(root)
button = tk.Button(window,text='Insert Text', command = lambda: insert_stuff(output))
output.pack()
button.pack()
window.mainloop()

正如Bryan Oakley所指出的"睡眠;在指定的时间内暂停整个程序。

但是,如果我理解正确的话,每次睡眠调用(或子进程轮询(完成时,您都会尝试更新ScrolledText小部件。

如果是这样,只需尝试将其添加到您的代码中即可:

scroll_object.update()

所以你的函数看起来是这样的:

def insert_stuff(scroll_object):
for i in range(10):
time.sleep(1)
string = f'{i}n'
scroll_object.insert(tk.INSERT,string)
scroll_object.update()

在tkinter中,它基本上是这样工作的(按照代码执行的顺序(:

  1. 您编写的代码贯穿始终
  2. 一旦到达主循环,就可以与窗口进行交互
  3. 一旦调用了一个函数(就像你按下"插入文本"按钮一样(,你为该函数编写的代码就会被执行(包括sleep语句(。但在这段时间内,没有其他代码被执行。因此,甚至tkinter代码,用于更新ScrolledText小部件以显示新条目。使用.update((函数调用,您可以手动刷新窗口小部件状态(这适用于所有类型的tkinter小部件(

希望这有帮助:(

编辑:正如Delrius Euphoria所指出的,窗口仍将被冻结(取决于子流程轮询所需的时间(。为了防止这种冻结发生,你有多种选择:

  1. 尝试使用异步函数
  2. 使用多处理模块和进程
  3. 使用多处理模块和

这三个选项都太复杂了,无法在这里解释,但我建议你试试选项2。只要去网上查一下就行了。长话短说,它基本上可以帮助你将某项任务外包给cpu的另一个线程。

最新更新