ipywidgets
ipywidgets copied to clipboard
Asynchronous "show/hide" TexteArea works in the classic Notebook but doesn't in JupyterLab
In our use case, the idea is to popup an TextArea when an error occurred in an asynchronous process and to hide it when the error condition disappears. The implementation uses a dedicated Output to display the TextArea when an error occurred. The Output.clear_output is then called to remove the TextArea when the problem is fixed.
In the following code, the asynchronous activity is simulated by a thread. This works smoothly in the classic Notebook but doesn't behave as expected in JupyterLab : the TextArea doesn't show up or remains displayed. The ipywidgets Jupyterlab extension is (obviously) properly installed and works as expected in other contexts.
Here is the Conda configuration I'm using:
ipykernel 5.3.1 py37h43977f1_0 conda-forge
ipython 7.16.1 py37h43977f1_0 conda-forge
ipython_genutil 0.2.0 py_1 conda-forge
ipywidgets 7.5.1 py_0 conda-forge
jupyter_client 6.1.5 py_0 conda-forge
jupyter_core 4.6.3 py37hc8dfbb8_1 conda-forge
jupyterlab 2.1.5 py_0 conda-forge
jupyterlab_server 1.2.0 py_0 conda-forge
notebook 6.0.3 py37hc8dfbb8_0 conda-forge
python 3.7.7 hcff3b4d_5
widgetsnbextension 3.5.1 py37_0 conda-forge
traitlets 4.3.3 py37hc8dfbb8_1 conda-forge
Here is some code reproducing the problem:
import threading
import time
from IPython.display import display
import ipywidgets as widgets
class AsyncErrorArea(object):
def __init__(self):
self.cnt = 0
self.err = False
self.wta = widgets.Textarea(layout = widgets.Layout(flex='1 1 auto', width='auto'),
placeholder='You should not see this TextArea!',
disabled=True)
weo_layout = widgets.Layout(flex='1 1 auto', width='auto')
weo_layout.border = "1px solid grey"
self.weo = widgets.Output(layout=weo_layout)
display(self.weo)
def show_error(self, err):
try:
self.err = True
txt = "Oops, the following error occurred: " + err
self.wta.value = txt
self.wta.rows = 2
with self.weo:
display(self.wta)
self.weo.layout.border = ""
except Exception as e:
print(e)
def hide_error(self):
try:
self.err = False
self.wta.value = ""
self.weo.clear_output()
self.weo.layout.border = "1px solid grey"
except Exception as e:
print(e)
def simul_activity(self):
try:
while not self.exit_requested:
self.cnt += 1
if not self.cnt % 3:
self.show_error("error #{}".format(self.cnt))
elif self.err:
self.hide_error()
time.sleep(1.)
except Exception as e:
print(e)
def start(self):
self.exit_requested = False
self.thread = threading.Thread(target=self.simul_activity)
self.thread.start()
def exit(self):
self.exit_requested = True
self.thread.join()
aea = AsyncErrorArea()
aea.start()
aea.exit()
Ping