@@ -238,55 +238,72 @@ Bar with wide Chinese (or other multibyte) characters
238238 for i in bar(range (10 )):
239239 time.sleep(0.1 )
240240
241- Showing multiple (threaded) independent progress bars in parallel
241+ Showing multiple independent progress bars in parallel
242242==============================================================================
243243
244- While this method works fine and will continue to work fine, a smarter and
245- fully automatic version of this is currently being made:
246- https://github.com/WoLpH/python-progressbar/issues/176
247-
248244.. code :: python
249245
250246 import random
251247 import sys
252- import threading
253248 import time
254249
255250 import progressbar
256251
257- output_lock = threading.Lock()
252+ BARS = 5
253+ N = 100
258254
255+ # Construct the list of progress bars with the `line_offset` so they draw
256+ # below each other
257+ bars = []
258+ for i in range (BARS ):
259+ bars.append(
260+ progressbar.ProgressBar(
261+ max_value = N,
262+ # We add 1 to the line offset to account for the `print_fd`
263+ line_offset = i + 1 ,
264+ max_error = False ,
265+ )
266+ )
259267
260- class LineOffsetStreamWrapper :
261- UP = ' \033 [F'
262- DOWN = ' \033 [B'
268+ # Create a file descriptor for regular printing as well
269+ print_fd = progressbar.LineOffsetStreamWrapper(sys.stdout, 0 )
263270
264- def __init__ ( self , lines = 0 , stream = sys.stderr):
265- self .stream = stream
266- self .lines = lines
271+ # The progress bar updates, normally you would do something useful here
272+ for i in range (N * BARS ):
273+ time.sleep( 0.005 )
267274
268- def write (self , data ):
269- with output_lock:
270- self .stream.write(self .UP * self .lines)
271- self .stream.write(data)
272- self .stream.write(self .DOWN * self .lines)
273- self .stream.flush()
275+ # Increment one of the progress bars at random
276+ bars[random.randrange(0 , BARS )].increment()
274277
275- def __getattr__ ( self , name ):
276- return getattr ( self .stream, name )
278+ # Print a status message to the `print_fd` below the progress bars
279+ print ( f ' Hi, we are at update { i + 1 } of { N * BARS } ' , file = print_fd )
277280
281+ # Cleanup the bars
282+ for bar in bars:
283+ bar.finish()
278284
279- bars = []
280- for i in range (5 ):
281- bars.append(
282- progressbar.ProgressBar(
283- fd = LineOffsetStreamWrapper(i),
284- max_value = 1000 ,
285- )
286- )
285+ # Add a newline to make sure the next print starts on a new line
286+ print ()
287287
288- if i:
289- print (' Reserve a line for the progressbar' )
288+ ******************************************************************************
289+
290+ Naturally we can do this from separate threads as well:
291+
292+ .. code :: python
293+
294+ import random
295+ import threading
296+ import time
297+
298+ import progressbar
299+
300+ BARS = 5
301+ N = 100
302+
303+ # Create the bars with the given line offset
304+ bars = []
305+ for line_offset in range (BARS ):
306+ bars.append(progressbar.ProgressBar(line_offset = line_offset, max_value = N))
290307
291308
292309 class Worker (threading .Thread ):
@@ -295,10 +312,12 @@ https://github.com/WoLpH/python-progressbar/issues/176
295312 self .bar = bar
296313
297314 def run (self ):
298- for i in range (1000 ):
299- time.sleep(random.random() / 100 )
315+ for i in range (N ):
316+ time.sleep(random.random() / 25 )
300317 self .bar.update(i)
301318
302319
303320 for bar in bars:
304321 Worker(bar).start()
322+
323+ print ()
0 commit comments