How to update a progress bar in a loop?
Asked Answered
F

2

8

What is the easy method to update Tkinter progress bar in a loop?

I need a solution without much mess, so I can easily implement it in my script, since it's already pretty complicated for me.

Let's say the code is:

from Tkinter import *
import ttk


root = Tk()
root.geometry('{}x{}'.format(400, 100))
theLabel = Label(root, text="Sample text to show")
theLabel.pack()


status = Label(root, text="Status bar:", bd=1, relief=SUNKEN, anchor=W)
status.pack(side=BOTTOM, fill=X)

root.mainloop()

def loop_function():
    k = 1
    while k<30:
    ### some work to be done
    k = k + 1
    ### here should be progress bar update on the end of the loop
    ###   "Progress: current value of k =" + str(k)


# Begining of a program
loop_function()
Filiate answered 9/4, 2016 at 12:3 Comment(0)
B
9

Here's a quick example of continuously updating a ttk progressbar. You probably don't want to put sleep in a GUI. This is just to slow the updating down so you can see it change.

from Tkinter import *
import ttk
import time

MAX = 30

root = Tk()
root.geometry('{}x{}'.format(400, 100))
progress_var = DoubleVar() #here you have ints but when calc. %'s usually floats
theLabel = Label(root, text="Sample text to show")
theLabel.pack()
progressbar = ttk.Progressbar(root, variable=progress_var, maximum=MAX)
progressbar.pack(fill=X, expand=1)


def loop_function():

    k = 0
    while k <= MAX:
    ### some work to be done
        progress_var.set(k)
        k += 1
        time.sleep(0.02)
        root.update_idletasks()
    root.after(100, loop_function)

loop_function()
root.mainloop()
Baden answered 9/4, 2016 at 17:34 Comment(2)
Using root.update_idletasks() makes the windows unresponsive. But root.update() doesn't make the window unresponsive.Head
@skarfa: No, calling time.sleep() in a tkinter gui program is what makes this unresponsive (because it temporarily suspends the gui's mainloop). The OP alludes to this in their description.Electret
V
0

Here is what I figured out:

First define a function to update the variable self.prog_precent = tk.DoubleVar() using set().

def prog_bar_update(self, value):

    self.prog_precent.set(value)

Then, update the root tk followed by calling self.after() in every 10 ms in the main loop, e.g.:

 count = 0
 for _ in range(100):

    do something ...
    count += 1 
    time.sleep(1)
    self.update()

    self.after(10, self.prog_bar_update, count)

Here is important to note that self might be different. In my case, it is the parent root - tk.

Finally run your main application:

if __name__ == "__main__":
    gs_gui = MainWindow(None)   # here is `MainWindow(tk.Tk):`
    gs_gui.mainloop()
Vinificator answered 31/10, 2023 at 18:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.