TKinter: 文本控件在程序运行时不更新
我有一个程序,它使用有限元方法进行计算,这个过程可能需要几分钟。因为程序在计算时可能会让用户觉得卡住了,所以我设计了一个功能,可以提前计算出它将进行多少次迭代,并在TKinter的文本框中显示进度百分比。
但问题是,当程序在迭代时,主窗口会卡住,只在最后更新文本,这对用户来说并不能很好地显示当前的计算进度。
下面是代码的具体部分:
progr+=dcompl
textbox.configure(state=NORMAL)
textbox.delete(1.0,2.0)
textbox.insert(1.0,"Processando... ")
textbox.insert(2.0,str(int(progr))+"%") #the variable progr is the current progress in %
textbox.configure(state=DISABLED)
每次程序经过特定代码部分时,它都会更新“progr”这个变量。
如果我只是把“progr”变量打印到控制台上,那是没问题的,但我希望用户能看到界面,而不是控制台。
有没有办法让TKinter窗口在程序运行时不卡住,并且可以实时更新文本呢?
2 个回答
0
如果我只是把“progr”这个变量打印到控制台,它运行得很好,但我希望用户能看到的是界面,而不是控制台。
如果你用一个标签代替文本,并更新一个Tkinter变量来显示内容,这样应该就没问题了。
def change_value():
## get the value because this program doesn't
## have a separate variable to use for the set()
val=progr.get()
if val < 100:
## show that the same function can be called many times with updates
textbox.after(50, change_value)
progr.set(val+2)
top=Tk()
textbox=Label(top, text="Processando... ")
textbox.grid()
progr=IntVar()
progr.set(1)
Label(top, textvariable=progr).grid(row=1)
change_value()
top.mainloop()
-1
你可以导入 threading
模块,把你的计算代码放在一个单独的 threading.Thread
里在后台运行,或者你也可以导入 subprocess
模块,让它在一个完全不同的进程中运行。在你的 tkInter 代码中,这部分代码必须在主线程里运行,你需要等到线程或进程发出信号告诉你它完成了,并把结果发回来。(记住,不要在后台线程中访问任何 tkInter 对象,因为 tkInter 工具包不是线程安全的,这样会导致偶尔崩溃。)
针对 Bryan 的评论:
怎么“等待”而不占用 CPU 呢?我有些应用程序使用了一个简单的循环,里面包含了 1 毫秒的 time.sleep()
,这样造成的性能影响几乎感觉不到。不过,要做到更好,你可能想用 tkinter 对象的 .after()
方法,反复调用一个函数来检查你后台计算的状态。