12

I would like to make an Image instance in a jupyter notebook to respond to click events - how can we do this? I also want to be able to identify the image that was clicked. It is simple to do so with buttons but not with images.

Fung
  • 7,530
  • 7
  • 53
  • 68
Dror Hilman
  • 6,837
  • 9
  • 39
  • 56

4 Answers4

4

After playing around with this, the only way I could do it so far is by using some javascript... in the python code, I have something like:

from ipywidgets import Image
from IPython.display import display, Javascript
im = Image(value=open(filename, 'rb').read())
im.add_class('the_image_class')

def on_image_click():
    #do something....
    return 

#Now, I wrote some javascript(jQuery) code like this...
js = ''' $(".the_image_class").on("click", function(e){
             var kernel = IPython.notebook.kernel;
             kernel.execute("on_image_click()");
          });'''

#then, run the javascript...
display(Javascript(js))

Which is kind of missing the point of using the widgets entirely in python... Is there a better way to bind python functions to the widgets events, without javascript?

Dror Hilman
  • 6,837
  • 9
  • 39
  • 56
  • it doesn't seem to work, what is add_class method? can you point to the documentation – SML May 03 '20 at 11:44
  • see: https://github.com/jupyter-widgets/ipywidgets/blob/5170757c4e9b93731ac840640ebf5dd499f6d47c/ipywidgets/widgets/domwidget.py#L30 – Dror Hilman May 04 '20 at 15:16
3
%%javascript
let kernel = IPython.notebook.kernel;
kernel.execute("on_image_click()");

or

can even get printed data back from python

%%javascript
let callback = {
        iopub: {
            // have a look at data on console for its structure
            output: (data) => {console.log(data)}}
        }
};
let kernel = IPython.notebook.kernel;
kernel.execute("on_image_click()", callback);
Lujun Weng
  • 101
  • 5
3

I find the other responses to be hacks (Injecting JavaScript on the page is not a good practice, and it might not work in JupyterLab).

You can have a look at ipyevents: https://github.com/mwcraig/ipyevents

It allows you to add event listeners to any widget, and it is developed by a core-ipywidgets maintainer.

Martin Renou
  • 424
  • 2
  • 10
0

I am not directly answering the question, but I have stumbled upon this question when solving a similar issue, maybe my solution will be useful to someone. I wanted to loop images in a jupyter notebook cell on click. Actually I would be ok with any interaction like button or even rerun of the cell. I was aiming for least amount of code, because this was for a presentation and I did not want to bother my audience with 30 lines of javascript just to loop some images. So this is the solution which loops through your images on Shift+Enter.

# Import and set a counter in one cell
from IPython.display import Markdown; slide = 0

# Loop images in a different cell
if not os.path.isfile('img{}.jpg'.format(slide)): slide = 0
slide +=1; Markdown("""<img src="img{}.jpg" style="height:100px">""".format(slide-1))
Paloha
  • 558
  • 6
  • 14