我有一个简单的TK gui和一个连接到按钮的函数中的长进程,当我点击按钮时我想要一个进度条。我想要一个进度条,我点击按钮,就像它开始一个很长很多的代码行
我该怎么做?这里是代码:
from tkinter import Button, Tk, HORIZONTAL
from tkinter.ttk import Progressbar
import time
class MonApp(Tk):
def __init__(self):
super().__init__()
bt1 = Button(self, text='Traitement', command=self.traitement)
bt1.grid()
self.progress = Progressbar(self, orient=HORIZONTAL,length=100, mode='indeterminate')
self.progress.grid()
self.progress.grid_forget()
def traitement(self):
self.progress.grid()
self.progress.start()
time.sleep(15)
## Just like you have many, many code lines...
self.progress.stop()
if __name__ == '__main__':
app = MonApp()
app.mainloop()
我尝试了很多东西,但我还没有找到怎么做。
如何在该应用中添加进度条?
答案 0 :(得分:15)
您可以在tkdocs
找到ttk.Progressbar
from tkinter import *
from tkinter.ttk import *
tk=Tk()
progress=Progressbar(tk,orient=HORIZONTAL,length=100,mode='determinate')
def bar():
import time
progress['value']=20
tk.update_idletasks()
time.sleep(1)
progress['value']=50
tk.update_idletasks()
time.sleep(1)
progress['value']=80
tk.update_idletasks()
time.sleep(1)
progress['value']=100
progress.pack()
Button(tk,text='foo',command=bar).pack()
mainloop()
最好使用threading
并在另一个帖子中运行您的代码。
像这样:
from tkinter import Button, Tk, HORIZONTAL
from tkinter.ttk import Progressbar
import time
import threading
class MonApp(Tk):
def __init__(self):
super().__init__()
self.btn = Button(self, text='Traitement', command=self.traitement)
self.btn.grid(row=0,column=0)
self.progress = Progressbar(self, orient=HORIZONTAL,length=100, mode='indeterminate')
def traitement(self):
def real_traitement():
self.progress.grid(row=1,column=0)
self.progress.start()
time.sleep(5)
self.progress.stop()
self.progress.grid_forget()
self.btn['state']='normal'
self.btn['state']='disabled'
threading.Thread(target=real_traitement).start()
if __name__ == '__main__':
app = MonApp()
app.mainloop()
答案 1 :(得分:0)
要使所有GUI元素自行修改(对于您的情况,要使进度条移动),执行必须命中app.mainloop()
。
在您的情况下,def traitement(self):
启动然后停止进度条,而没有触及主循环,因此它无法在GUI上可视地反映预期的进度条移动。这里的问题是,当执行到达主循环时,进度条被配置为“停止”状态。
因此,最好在不同的 Thread 上执行耗时的活动,如@xmcp
所示但是,如果您不想使用线程,则可以使用 after 方法来实现所需的目标:
def stop_progressbar(self):
self.progress.stop()
def traitement(self):
self.progress.grid()
self.progress.start()
self.after(15000, self.stop_progressbar)
## Call Just like you have many, many code lines...
上面的代码使用了 self.after()方法,它将执行 stop_progressbar 方法以在15秒后停止,而不是 time.sleep()< / strong>阻止主线程。