Search code examples
pythonmultithreadingjupyter-labipywidgets

Ipywidget with periodic update using thread


I am trying to periodically record the value of a slider widget. I have checked out the official document on Asynchronous Widgets. But for my code, it seems blocking still happens.

import threading
import time
from ipywidgets import widgets

w = widgets.IntSlider()
out = widgets.Output()
def record():
   for i in range(10):
       time.sleep(1)
       with out:
           print(f"record {w.value}")
           
t = threading.Thread(target=record)

display(w,out)
t.start()
t.join()

I expected the output of the slider value at every second as I drag the slider. Instead, it only prints 0s during the drag.

I also tried to put both processes in threads (and use the observe method for slider), doesn't work as well.

Environment: Jupyter lab 3.2.1


Solution

  • The issue comes from calling the join function at the end of your code. Calling join on your thread prevents your widget from updating. I would also pass your widgets w and your output out as arguments to your `record function (as in here). So overall, the code looks like that:

    import threading
    import time
    from ipywidgets import widgets
    
    w = widgets.IntSlider()
    out = widgets.Output()
    def record(w,out):
       for i in range(10):
           time.sleep(1)
           with out:
               print(f"record {w.value}")
               
    t = threading.Thread(target=record,args=(w,out,))
    
    display(w,out)
    t.start()
    

    And an example of the output can be seen below:

    record 0
    record 30
    record 30
    record 50
    record 72
    record 97
    record 80
    record 80
    record 35
    record 35