I want to:
- Read from serial port (infinite loop)
- when "STOP" button pressed --> Stop reading and plot data
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 = '