我在python 2.7.10中使用Tkinter构建了一个GUI程序。
无论如何,它的工作完美无缺。
不幸的是,它简单地进入了windows dreaded" Not Responding"与...互动时的状态。
这里是简短的布局:
启动脚本启动主脚本。 主脚本读取设置文件并引导GUI脚本。 GUI脚本启动GUI。 用户输入一个术语以在一系列文件中搜索。 GUI脚本进入侧脚本来处理文件和检索结果。 Side脚本继承了GUI脚本的某些方面。 Side脚本尝试在使用继承元素时更新用户; GUI没有它。 在返回GUI脚本并显示结果之前,GUI没有短暂响应。
这就是我需要的方式:
启动脚本启动主脚本。 主脚本读取设置文件并引导GUI脚本。 GUI脚本启动GUI。 用户输入一个术语以在一系列文件中搜索。 GUI脚本进入侧脚本来处理文件和检索结果。 Side脚本继承了GUI脚本的某些方面。 Side脚本使用GUI元素在工作时使用进度条和图像更新用户。 GUI返回GUI脚本并显示结果。
我已经建立了进度条,但图像尚未显示,但如果进度条不起作用,我不会在图像上浪费时间。
样本不可能,没有被使用但是显示点代码; GUI;
import Tkinter, PIL, SideScript1
Tkinter()
ShowText()
ShowStuff()
input = GetInput()
ShowProgressBar()
SideScript1.processfilesbasedoninput(input, progressbarcontrolvar)
DisplayResults()
SideScript1
def proccessfilesbasedoninput(input, pbcv):
DoStuff()
pbcv.gofurther(5)
DoMoreStuff()
pbcv.goevenfurther(10)
a1sauce = RandomMathsStuffs()
for all the data in every file in that one directory:
ReadData()
pbcv.goabitfurther(a1sauce)
if data is what I want:
break
pbcv.step(-100)
return data
我想我的问题是,如何让GUI更新这些元素而不是失去意识?
我们正在谈论10万个文件并完成1.5秒。
更新:此问题已被标记为另一个问题的副本。是吗?是的。但这都是因为我((现在仍然)不确定如何搜索这类问题,以及那里的三个解决方案; multithreading
,multiprocessing
和较小的任务。不幸的是,该程序是为了在单个线程和进程上运行而构建的,如果没有完全重写,获得预期的GUI响应会导致大幅减速,如果它完全有效的话。
我确实看到了这个问题,因为TKinter是一个阻止模块。不幸的是,我对于如何在不造成质量错误和完全重写的情况下解除阻止它的想法很清楚。
答案 0 :(得分:0)
链接的重复问题得到了答案。一个糟糕的 - 但答案一点也不错。
update_idletasks
。
我试过了,而且,它工作了!好。排序。
起初工作,然后出现了同样的结果。 GUI暂时冻结。
然后一个想法突然出现在我脑海中。为什么不试试update
?
我这样做了,并且它按照我需要的方式工作,然而,它有很大的性能影响 - 几乎与update_idletasks
相同。
为了解决这个新问题,我添加了一些数学来导致更新发生,在我的情况下,每300个文件,而不是每个文件 - 平衡性能命中和用户不立即删除我的程序,因为是的,这会对你的资源产生影响。不,我最初没有注意到这个建议。先拍,稍后再问问吧?
我是如何使用它的?很高兴我问!这是一个例子;
#GUI Code
DoStuff()
SideScript1.proccessdata(arg, kwarg, debate)
DoMoreStuff()
#File Management Code
DoStuff()
filenumber = 0
maxfilenumber = 0
for every file I need to search:
SearchFile()
filenumber +=1
if filenumber == maxfilenumber:
tkinter.update() #in my case, it was tkinst, or "TkInter Instance", since it was inherited from the GUI attributes.
filenumber = 0
if data is what I want:
break
return data
我不确定所有后端和事实,但update()
似乎比update_idletasks()
更加用户友好且更快,并且更不容易出错和减速
我的恶作剧现在恢复正常,以60秒((30?120?2.5亿?)的速度运行一秒钟,平稳而高效地进行 - 而且每次我都没有坐下来罢工再问它了!
感谢@Rawing试图提供帮助!