Home > database >  Kill a loop with Button Jupiter Notebook?
Kill a loop with Button Jupiter Notebook?

Time:02-23

I want to:

  • Read from serial port (infinite loop)
  • when "STOP" button pressed --> Stop reading and plot data

From enter image description here

CodePudding user response:

I think problem is as in all Python scripts with long-running code - it runs all code in one thread and when it runs while True loop (long-running cod) then it can't run other functions at the same time.

You may have to run your function in separated thread - and then main thread can execute on_button_clicked

This version works for me:

from IPython.display import display
import ipywidgets as widgets
import time
import threading

button = widgets.Button(description="STOP!") 
output = widgets.Output()

display(button, output)

break_cicle = True

def on_button_clicked(event):
    global break_cicle
    
    break_cicle = False

    print("Button pressed: break_cicle:", break_cicle)
    
button.on_click(on_button_clicked)

def function():
    while break_cicle:
        print("While loop: break_cicle:", break_cicle)
        time.sleep(1)
    print("Done")
    
threading.Thread(target=function).start()

Maybe Jupyter has some other method for this problem - ie. when you write functions with async then you can use asyncio.sleep() which lets Python to run other function when this function is sleeping.


EDIT:

Digging in internet (using Google) I found post on Jyputer forum

Interactive widgets while executing long-running cell - JupyterLab - Jupyter Community Forum

and there is link to module jupyter-ui-poll which shows similar example (while-loop Button) and it uses events for this. When function pull() is executed (in every loop) then Jupyter can send events to widgets and it has time to execute on_click().

import time
from ipywidgets import Button
from jupyter_ui_poll import ui_events

# Set up simple GUI, button with on_click callback
# that sets ui_done=True and changes button text
ui_done = False
def on_click(btn):
    global ui_done
    ui_done = True
    btn.description = '           
  • Related