tkinter gui with progress bar

后端 未结 2 1106
抹茶落季
抹茶落季 2020-12-30 06:51

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

相关标签:
2条回答
  • 2020-12-30 07:13

    You can find ttk.Progressbar at 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.

    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()
    
    0 讨论(0)
  • 2020-12-30 07:16

    For all the GUI elements to modify themselves (in your case, for the progress bar to move) the execution must hit 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.

    Hence, it is a good idea to execute time consuming activities on a different Thread as shown by @xmcp

    However, if you DO NOT want to use threading, you can use the after method to achieve what you want:

    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_progressbar method to stop after 15 seconds, instead of time.sleep() which blocks the mainthread.

    0 讨论(0)
提交回复
热议问题