Pierrick Rambaud
Pierrick Rambaud

Reputation: 2400

why cannot I print in jupyter lab using ipywidgets class?

I use the ipyvuetify librairy to create dashboard in a Jupyter environment. The lib works super nicely but I'm struggling with Jupyterlab and voila that seems to have the same behavior with respect to this problem:

let's assume I want to create a widget that when clicked print a message :

import ipyvuetify as v 

class Test(v.Btn):
    
    def __init__(self, msg):
        
        self.msg = msg
        
        super().__init__(children=['click'])
        
        self.on_event('click', self._on_click)
        
    def _on_click(self, widget, event, data):
        
        print(self.msg)
        
        return
    
btn = Test(toto)
btn

If I run this code from Jupyter Notebook, everything works fine, the msg is printed after the btn cell output. If I do the same in Jupyterlab, the print statement ends up in the log.

now if run :

btn._on_click(None, None, None)

the msg is printed in both Jupyterlab and Jupyter Notebook.

Can someone explain me why there is a behaviour difference and maybe how to make sure that my print statement ends up in the main workflow and not in the log ?

Upvotes: 1

Views: 1018

Answers (1)

guimillet
guimillet

Reputation: 306

Indeed, JupyterLab has implemented a different mechanism than Jupyter Notebook to capture output, via the Output widget of ipywidget:

import ipyvuetify as v
import ipywidgets as w

class Test(v.Btn):
    output = w.Output()
    def __init__(self, msg):
        
        self.msg = msg
        
        super().__init__(children=['click'])
        
        self.on_event('click', self._on_click)
        
    @output.capture()
    def _on_click(self, widget, event, data):
        
        print(self.msg)
        
        return

    def _ipython_display_(self):
        display(super(),self.output)

    
btn = Test('toto')
btn

Ipywidget documentation: the output from _on_click is directed to output by using either a context manager with self.output: over print(), or the capture decorator to capture all the output produced by the _on_click function (example above).

Some explanation in https://github.com/jupyterlab/jupyterlab/issues/3151#issuecomment-339476572:

We kludged a backwards-compatibility workaround in the classic notebook, but we didn't in jupyterlab. Part of the reason is that it is much harder to write kludgy workarounds in jlab :).

Essentially, the technical issue is that a widget comm message from the browser to the client would need to set the output callback to append output to the current output area - but IIRC it's hard from a mime renderer to get a handle on the output area that contains it.

Upvotes: 1

Related Questions