2014-11-03 73 views
0

我有一个使用有限元方法进行计算的程序,可能需要花费几分钟时间。 由于该程序对于用户来说可能已冻结,因此我计算了它预先计算的迭代次数,并将百分比进度打印到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”变量打印到控制台,它工作得很好,但我希望用户在查看UI而不是在控制台。

有没有什么办法可以让TKinter窗口不冻结并在程序运行时更新文本?

回答

-1

您可以导入threading模块并在单独的threading.Thread的背景中运行您的编号处理代码,或者您可以导入subprocess模块并在完全独立的过程中运行它。在必须留在主线程中的tkInter代码中,您需要等到线程/子进程向您发送完成并发送结果的信号。 (切记不要从后台线程访问任何Tkinter的对象,但:在Tkinter的工具包是不是线程安全的,这将导致零星的崩溃。)

针对布莱恩的评论:

你是如何“等待”无需捆绑CPU?我的一些应用程序使用了一个简单的循环,其中包含1毫秒的time.sleep(),所得到的性能并不明显。但是,要正确执行此操作,您可能需要使用tkinter对象的.after()机制来重复调用一个函数来检查背景编号的运算状态。

+1

您从不想在GUI的主线程中调用'sleep',因为它会在整个GUI处于休眠状态时冻结整个GUI。 – 2014-11-03 23:18:29

+0

谢谢。我使用线程模块来创建一个不同的线程,这解决了我的问题。 – 2014-11-04 20:02:47

0

如果我只是将“progr”变量打印到控制台,它工作得很好,但我希望用户在查看UI而不是在控制台。

如果您使用标签而不是文本并更新打印的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() 
相关问题