Search code examples
pythontkinter

Tkinter GUI with progress bar


I have a simple Tk GUI and a long process in a function attached to a button. I want a progress bar when I click on the button, just like it starts a long process.

How can I do that? This is my current 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()

How can I put a progress bar in that application?


Solution

  • You can find ttk.Progressbar at tkdocs

    import time
    from tkinter import *
    from tkinter.ttk import *
    
    tk = Tk()
    progress = Progressbar(tk, orient=HORIZONTAL, length=100, mode='determinate')
    
    
    def bar():
        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.

    Like this:

    import threading
    import time
    from tkinter import Button, Tk, HORIZONTAL
    from tkinter.ttk import Progressbar
    
    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()