TKinter: 文本控件在程序运行时不更新

0 投票
2 回答
1970 浏览
提问于 2025-05-01 10:31

我有一个程序,它使用有限元方法进行计算,这个过程可能需要几分钟。因为程序在计算时可能会让用户觉得卡住了,所以我设计了一个功能,可以提前计算出它将进行多少次迭代,并在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() 方法,反复调用一个函数来检查你后台计算的状态。

撰写回答