Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Render nested progress bars in the same container in IPython. #1504

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
36 changes: 27 additions & 9 deletions tqdm/notebook.py
Expand Up @@ -37,25 +37,28 @@
if IPY == 32:
from IPython.html.widgets import HTML
from IPython.html.widgets import FloatProgress as IProgress
from IPython.html.widgets import HBox
from IPython.html.widgets import HBox, VBox
IPY = 3
else:
from ipywidgets import HTML
from ipywidgets import FloatProgress as IProgress
from ipywidgets import HBox
from ipywidgets import HBox, VBox
except ImportError:
try: # IPython 2.x
from IPython.html.widgets import HTML
from IPython.html.widgets import ContainerWidget as HBox
from IPython.html.widgets import ContainerWidget as VBox
from IPython.html.widgets import FloatProgressWidget as IProgress
IPY = 2
except ImportError:
IPY = 0
IProgress = None
HBox = object
VBox = object

try:
from IPython.display import display # , clear_output
from IPython.display import clear_output, display
clear_output(wait=False) # Necessary when rerunning cells
except ImportError:
pass

Expand Down Expand Up @@ -91,6 +94,8 @@ class tqdm_notebook(std_tqdm):
"""
Experimental IPython/Jupyter Notebook widget using tqdm!
"""
outer_container = None

@staticmethod
def status_printer(_, total=None, desc=None, ncols=None):
"""
Expand Down Expand Up @@ -143,9 +148,6 @@ def display(self, msg=None, pos=None,
# goal is to keep all infos if error happens so user knows
# at which iteration the loop failed.

# Clear previous output (really necessary?)
# clear_output(wait=1)

if not msg and not close:
d = self.format_dict
# remove {bar}
Expand Down Expand Up @@ -179,14 +181,21 @@ def display(self, msg=None, pos=None,

# Special signal to close the bar
if close and pbar.bar_style != 'danger': # hide only if no error
# Remove self.container from the list of children of outer_container
tqdm_notebook.outer_container.children = tuple(
c for c in tqdm_notebook.outer_container.children if c is not self.container)
try:
self.container.close()
if abs(self.pos) == 0:
tqdm_notebook.outer_container.close()
except AttributeError:
self.container.visible = False
self.container.layout.visibility = 'hidden' # IPYW>=8

if check_delay and self.delay > 0 and not self.displayed:
display(self.container)
tqdm_notebook.outer_container.children += (self.container,)
if abs(self.pos) == 0:
display(tqdm_notebook.outer_container)
self.displayed = True

@property
Expand Down Expand Up @@ -231,11 +240,18 @@ def __init__(self, *args, **kwargs):
# Replace with IPython progress bar display (with correct total)
unit_scale = 1 if self.unit_scale is True else self.unit_scale or 1
total = self.total * unit_scale if self.total else self.total

if abs(self.pos) == 0:
tqdm_notebook.outer_container = VBox()

self.container = self.status_printer(self.fp, total, self.desc, self.ncols)

self.container.pbar = proxy(self)
self.displayed = False
if display_here and self.delay <= 0:
display(self.container)
tqdm_notebook.outer_container.children += (self.container,)
if abs(self.pos) == 0:
display(tqdm_notebook.outer_container)
self.displayed = True
self.disp = self.display
self.colour = colour
Expand Down Expand Up @@ -275,10 +291,12 @@ def close(self):
super(tqdm_notebook, self).close()
# Try to detect if there was an error or KeyboardInterrupt
# in manual mode: if n < total, things probably got wrong
pos = abs(self.pos)
leave = pos == 0 if self.leave is None else self.leave
if self.total and self.n < self.total:
self.disp(bar_style='danger', check_delay=False)
else:
if self.leave:
if leave:
self.disp(bar_style='success', check_delay=False)
else:
self.disp(close=True, check_delay=False)
Expand Down