tkinter gui带进度条

时间:2015-11-17 22:48:13

标签: python tkinter

我有一个简单的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()

我尝试了很多东西,但我还没有找到怎么做。

如何在该应用中添加进度条?

2 个答案:

答案 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>阻止主线程。