Python 带有进度条的 tkinter gui
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33768577/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
tkinter gui with progress bar
提问by j666
I have a simple TK gui and a long process in a function attached to a button and I want a progress bar when I click on the button. I want a progress bar went i click on the button, just like it start a long proc with many, many code line
我有一个简单的 TK gui 和一个附加到按钮的函数的漫长过程,当我点击按钮时,我想要一个进度条。我想要一个进度条,我点击按钮,就像它开始一个很长的过程,有很多很多代码行
how can i do that? here the code:
我怎样才能做到这一点?这里的代码:
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()
I have tried many things, but I don't haven't found how to.
我尝试了很多东西,但我还没有找到方法。
How can I put a progress bar in that app?
如何在该应用程序中放置进度条?
采纳答案by xmcp
You can find ttk.Progressbar
at tkdocs
你可以ttk.Progressbar
在tkdocs找到
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()
It's better to use threading
and run your code in another thread.
最好threading
在另一个线程中使用和运行您的代码。
Like this:
像这样:
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()
回答by MightyInSpirit
For all the GUI elements to modify themselves (in your case, for the progress bar to move) the execution must hit app.mainloop()
.
对于所有要修改自己的 GUI 元素(在您的情况下,为了移动进度条),执行必须点击app.mainloop()
。
In your case, def traitement(self):
starts and then stops the progressbar without hitting the mainloop, so it fails to visibly reflect the intended progressbar movement on the GUI. The catch here is, when the execution hits mainloop, progressbar is configured to 'stop' state.
在您的情况下,def traitement(self):
在不击中主循环的情况下启动然后停止进度条,因此它无法在 GUI 上明显反映预期的进度条移动。这里的问题是,当执行到达主循环时,进度条被配置为“停止”状态。
Hence, it is a good idea to execute time consuming activities on a different Threadas shown by @xmcp
因此,在不同的线程上执行耗时的活动是一个好主意,如@xmcp 所示
However, if you DO NOT want to use threading, you can use the aftermethod to achieve what you want:
但是,如果您不想使用线程,则可以使用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...
The above code used self.after()method which will execute the stop_progressbarmethod to stop after 15 seconds, instead of time.sleep()which blocks the mainthread.
上面的代码使用了self.after()方法,它会执行stop_progressbar方法在 15 秒后停止,而不是阻塞主线程的 time.sleep ()。