使用 Button Jupyter Notebook 终止循环?

2023-12-08

我想要:

  • 从串口读取(无限循环)
  • 当按下“STOP”按钮时 --> 停止读取并绘制数据

From 如何通过按键终止 while 循环?我以使用键盘中断为例,这有效,但我想使用一个按钮。

键盘中断示例

weights = []
times = [] 
#open port 
ser = serial.Serial('COM3', 9600)
try:
   while True: # read infinite loop
       #DO STUFF
       line = ser.readline()   # read a byte string
       if line:
           weight_ = float(line.decode())  # convert the byte string to a unicode string
           time_ = time.time()
           weights.append(weight_)
           times.append(time_)
           print (weight_)
#STOP it by keyboard interup and continue with program 
except KeyboardInterrupt:
   pass
#Continue with plotting

不过我想用一个显示的按钮来做到这一点(更方便人们使用)。 我尝试过制作一个按钮(在 Jupyter 笔记本中)当按下break_cicle=False时,但是按下按钮时循环不会中断:

 #make a button for stopping the while loop 
button = widgets.Button(description="STOP!") #STOP WHEN THIS BUTTON IS PRESSED
output = widgets.Output()
display(button, output)
break_cicle=True


def on_button_clicked(b):
    with output:
        break_cicle = False # Change break_cicle to False
        print(break_cicle)
        
ser.close()   
button.on_click(on_button_clicked)
ser = serial.Serial('COM3', 9600)
try:
    while break_cicle:

        print (break_cicle)
        line = ser.readline()   # read a byte string
        if line:
            weight_ = float(line.decode())  # convert the byte string to a unicode string
            time_ = time.time()
            weights.append(weight_)
            times.append(time_)
            print (weight_)
except :
    pass

ser.close()    

全局不起作用的示例

from IPython.display import display
import ipywidgets as widgets

button = widgets.Button(description="STOP!") #STOP WHEN THIS BUTTON IS PRESSED
output = widgets.Output()
display(button, output)
break_cicle=True

def on_button_clicked():
    global break_cicle #added global
    with output:
        
        break_cicle = False # Change break_cicle to False
        print ("Button pressed inside break_cicle", break_cicle)
    
    
button.on_click(on_button_clicked)
try:
    while break_cicle:
        print ("While loop break_cicle:", break_cicle)
        time.sleep(1)
except :
    pass
print ("done")

尽管我按了几次按钮,但从下图中您可以看到它从未打印“Button Pressed inside Break_cicle”。

enter image description here


我认为问题就像所有具有长时间运行代码的Python脚本一样——它在一个线程中运行所有代码,并且当它运行时while True循环(长时间运行的代码),那么它不能同时运行其他函数。

您可能必须在单独的线程中运行您的函数 - 然后主线程才能执行on_button_clicked

这个版本对我有用:

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()

也许 Jupyter 有其他方法可以解决这个问题 - 即。当你编写函数时async那么你可以使用asyncio.sleep()它允许Python在该函数休眠时运行其他函数。


EDIT:

在互联网上挖掘(使用谷歌)我在 Jupyter 论坛上找到了帖子

执行长时间运行的单元时的交互式小部件 - JupyterLab - Jupyter 社区论坛

并且有模块链接jupyter-ui-民意调查其中显示了类似的示例(while-loop + Button)并且它使用events为了这。当函数pull()执行(在每个循环中)然后 Jupyter 可以将事件发送到小部件并且它有时间执行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 = '????'

btn = Button(description='Click Me')
btn.on_click(on_click)
display(btn)

# Wait for user to press the button
with ui_events() as poll:
    while ui_done is False:
        poll(10)          # React to UI events (upto 10 at a time)
        print('.', end='')
        time.sleep(0.1)
print('done')

In 源代码我可以看到它使用asyncio为了这。


EDIT:

版本有多重处理

进程不共享变量,因此需要Queue将信息从一个进程发送到另一个进程。

示例发送消息来自button to function。如果您想从以下位置发送消息function to button那么最好使用第二个队列。

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

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

display(button, output)

queue = multiprocessing.Queue()

def on_button_clicked(event):
    queue.put('stop')
    print("Button pressed")
    
button.on_click(on_button_clicked)

def function(queue):
    
    while True:
        print("While loop")
        time.sleep(1)
        
        if not queue.empty():
            msg = queue.get()
            if msg == 'stop':
                break
            #if msg == 'other text':             
            #    ...other code...
            
    print("Done")
    
multiprocessing.Process(target=function, args=(queue,)).start()

或更类似于之前的

def function(queue):

    break_cicle = True
    
    while break_cicle:
        print("While loop: break_cicle:", break_cicle)
        time.sleep(1)
        
        if (not queue.empty()) and (queue.get() == 'stop'):
            break_cicle = False
        
    print("Done")

EDIT:

版本有asyncio

Jupyter 已经在运行asynio event loop我添加async function到这个循环。以及功能用途await功能类似于asyncio.sleep so asynio event loop有时间运行其他函数 - 但如果函数只能运行标准(非异步)函数,那么它就无法工作。

from IPython.display import display
import ipywidgets as widgets
import asyncio

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)

async def function():   # it has to be `async`
    while break_cicle:
        print("While loop: break_cicle:", break_cicle)
        await asyncio.sleep(1)   # it needs some `await` functions
    print("Done")
    
loop = asyncio.get_event_loop()    
t = loop.create_task(function())  # assign to variable if you don't want to see `<Task ...>` in output
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Button Jupyter Notebook 终止循环? 的相关文章

随机推荐

  • 访问 HttpParams 的所有条目

    有没有一种方法可以迭代所有条目HttpParams object 其他人也有类似的问题 打印 HttpParams HttpUriRequest 的内容 但答案并没有真正起作用 当调查时基本Http参数我看到有一个HashMap里面 但无法
  • 在 virtualenv 中的 GPU 集群上运行 TensorFlow

    我按照这些在 virtualenv 中安装了 GPU 版本的张量流指示 问题是 我在启动会话时遇到分段错误 也就是说 这段代码 import tensorflow as tf sess tf InteractiveSession 退出并出现
  • Debian 没有名为 numpy 的模块

    我已经在 Debian 上安装了 Python Numpy 使用 apt get 安装 python numpy 但是当运行 Python shell 时 我得到以下信息 Python 2 7 10 default Sep 9 2015 2
  • @Injectable() 装饰器和提供者数组

    Injectable 装饰器中 root 中提供的服务是否仍然必须位于模块的提供者数组中 The 角度文档并没有真正给我答案或者我不太明白 在我的核心文件夹中 我有一个在根目录中提供的身份验证服务 我不想将我的核心模块导入到应用程序模块中
  • React 将历史记录传递给路由器中定义的组件

    我的 App js 中有这个路由器
  • 如何更改默认 backBarButtonItem 上的颜色/图像?

    我需要更改默认的 self navigationItem backBarButtonItem 的颜色 为了实现这一点 我创建了一个自定义 Button 类并按如下方式实现它 void viewDidLoad super viewDidLoa
  • MVC3 在重定向到操作时销毁会话

    我在 MVC3 应用程序中遇到会话问题 在一个控制器中 我收到一个发布请求 然后在重定向到控制器 get 方法之前将值添加到会话中 问题是 在 GET 请求中 会话值返回 null 即使在 POST 请求中设置了会话值 HttpPost p
  • 带有复选框问题的 jQuery 禁用按钮

    我有以下代码 在选中复选框时启用按钮 http jsfiddle net ERfWz 1 以下是我的 HTML 页面中的代码片段 它非常相似 但由于某种原因它不起作用 我想我可能已经看它太久了
  • SmoothState.Js 页面更改后重新初始化页面脚本

    我使用 SmoothState js 进行页面转换 它工作正常并使用 ajax 加载新页面 然而 我在每个页面上都有需要重新初始化的 JS 脚本 并且我无法让它们始终出现在页面转换中 根据常见问题解答 smoothState js 提供了
  • 如何创建一个新对象,其中键作为一个对象的值,该对象作为值?

    我的问题有点类似于this 我有一个映射 其键为 objectType1 值为 objectType1 无效的 type ObjectType1 key string value string const newMap new Map
  • 在网页中嵌入 Windows 窗体用户控件的步骤

    我正在 Visual Studio 2005 中开发一个 Windows 窗体用户控件 它是一个文件上传控件 仅使用 2 个元素 显示 openfiledialog 的按钮 打开文件对话框 我已经在 html 页面中添加了一个带有类 id
  • Hibernate EntityManager.merge() 不更新数据库

    我有一个使用 Hibernate 的 Spring MVC Web 应用程序 我的问题是em merge拨打电话后没有回复 这是我的控制器 RequestMapping value updDep method RequestMethod P
  • 从 Mysql DB 填充 JFreechart TimeSeriesCollection?

    我正在尝试在我的应用程序中制作一个图表 该图表可以返回几个月内各天的温度 该图表是 JFreechart TimeSeriesCollection 我无法让该图表从数据库读取正确的数据 它显示了一些值 但不是全部 并且不显示正确的时间 为了
  • 为什么 gc() 不释放内存?

    我在一个上运行模拟Windows 64 位计算机 with 64 GB 内存 内存使用达到55 完成模拟运行后 我通过以下方式删除工作空间中的所有对象rm list ls 后面跟着一个double gc 我认为这将为下一次模拟运行释放足够的
  • 如何使用特定网络接口(或特定源 IP 地址)进行 Ping?

    根据这个链接 使用 System Net NetworkInformation 有没有办法将 ping 绑定到特定接口 ICMP 不能绑定到网络接口 与基于套接字的东西不同 ICMP 不是基于套接字的 ping 将根据路由表发送到适当的端口
  • 列表视图滚动不平滑

    我有一个自定义列表视图 显示用户和照片 我从 API 检索数据 它提供 JSON 输出 我的问题是列表视图滚动不顺畅 它挂起一秒钟并滚动 它重复相同的操作直到我们到达末尾 我认为这可能是因为我正在 UI 线程上运行与网络相关的操作 但即使在
  • 实体框架能否在保存时自动将日期时间字段转换为 UTC?

    我正在使用 ASP NET MVC 5 编写一个应用程序 我要存储在数据库中的所有日期时间必须首先从本地时区转换为 UTC 时区 我不确定在请求周期内最好的地方在哪里 我可以在控制器中通过 ViewModel 规则后将每个字段转换为 UTC
  • JS 中的猜数字游戏

    我想创建一个数字游戏 用户输入 1 100 之间的数字 脚本将尝试猜测 10 次用户的输入 如果猜对的数字在 10 以内 则用户获胜 否则用户获胜 到目前为止 我让它正常工作 除了我在尝试让它显示游戏结束时的猜测数量时遇到问题 例如 如果进
  • 如何使用模型/视图/控制器方法制作 GUI?

    我需要理解模型 视图 控制器方法背后的概念以及如何以这种方式编写 GUI 这只是一个非常基本 简单的 GUI 有人可以向我解释如何使用 MVC 重写这段代码吗 from tkinter import class Application Fr
  • 使用 Button Jupyter Notebook 终止循环?

    我想要 从串口读取 无限循环 当按下 STOP 按钮时 gt 停止读取并绘制数据 From 如何通过按键终止 while 循环 我以使用键盘中断为例 这有效 但我想使用一个按钮 键盘中断示例 weights times open port