I want to know how to run a progress bar and some other work simultaneously, then when the work is done, stop the progress bar in Python (2.7.x)
import sys, time
def progress_bar():
while True:
for c in ['-','\\','|','/']:
sys.stdout.write('\r' + "Working " + c)
sys.stdout.flush()
time.sleep(0.2)
def work():
*doing hard work*
How would I be able to do something like:
progress_bar() #run in background?
work()
*stop progress bar*
print "\nThe work is done!"
You could run a thread in the background using the threading
module. For example:
def run_progress_bar(finished_event):
chars = itertools.cycle(r'-\|/')
while not finished_event.is_set():
sys.stdout.write('\rWorking ' + next(chars))
sys.stdout.flush()
finished_event.wait(0.2)
# somewhere else...
finished_event = threading.Event()
progress_bar_thread = threading.Thread(target=run_progress_bar, args=(finished_event,))
progress_bar_thread.start()
# do stuff
finished_event.set()
progress_bar_thread.join()
You can create a separate thread that displays the progress bar. This could be done as shown in @icktoofay's answer, however I would prefer something like the following implementation which derives a new thread subclass for the task. One advantage to this approach is that everything is self contained in each instance of the new class so you don't need global variables for communications between them and the main thread.
import sys
import threading
import time
class ProgressBarThread(threading.Thread):
def __init__(self, label='Working', delay=0.2):
super(ProgressBarThread, self).__init__()
self.label = label
self.delay = delay # interval between updates
self.running = False
def start(self):
self.running = True
super(ProgressBarThread, self).start()
def run(self):
label = '\r' + self.label + ' '
while self.running:
for c in ('-', '\\', '|', '/'):
sys.stdout.write(label + c)
sys.stdout.flush()
time.sleep(self.delay)
def stop(self):
self.running = False
self.join() # wait for run() method to terminate
sys.stdout.write('\r' + len(self.label)*' ' + '\r') # clean-up
sys.stdout.flush()
def work():
time.sleep(5) # *doing hard work*
pb_thread = ProgressBarThread('Computing')
pb_thread.start()
work()
pb_thread.stop()
print("The work is done!")