如何在 运行 代码时更新 ipywidget 值?

How do I update ipywidget values while running code?

所以我想在 Jupyter 笔记本中创建一个简单的 UI,其中:

  1. 计数器“数字”每秒递增
  2. 如果选中复选框“暂停”,则“数字”不会递增
  3. 如果按下“触发”按钮,则无论暂停状态如何,“数字”都会递减

到目前为止,我尝试了以下代码的几个变体,但都不起作用;当 运行 while 循环时,小部件值似乎没有更新。有没有办法修复它或其他方法来做到这一点?谢谢!

import ipywidgets as widgets
import time
from IPython.display import display, clear_output

btn = widgets.Button(description = "Trigger")
pause = widgets.Checkbox(value = False, description = "Paused?")
number = widgets.Label("0")
wid = widgets.VBox([btn, number, pause])
display(wid)

def triggered(b):
    number.value = str(int(number.value) - 1)

btn.on_click(triggered)

while True:
    time.sleep(1)
    while (pause.value == True):
        time.sleep(3)
    number.value = str(int(number.value) + 1)

ac24 所述,诀窍是 运行 您的计数器函数在不同的线程中。您可以使用 threading 库来做到这一点。下面,我定义了一个函数 counter 并在不同的线程中启动它。这样,当 counter 函数处于 运行ning 时,用户仍然能够与小部件进行交互。 要牢记的一件重要事情是,一旦您启动线程,就没有多少优雅的方法可以终止它。这意味着最好设置一个 total_duration 变量而不是使用 while True.

查看下面的代码:

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

btn = widgets.Button(description = "Trigger")
pause = widgets.Checkbox(value = False, description = "Paused?")
number = widgets.Label("0")

wid = widgets.VBox([btn,number,pause])
display(wid)

def triggered(b):
    number.value = str(int(number.value) - 1)
    
btn.on_click(triggered)
    
def counter(number,pause,total_duration):
    for t in range(total_duration):
        if not pause.value:
            time.sleep(1)
            number.value = str(int(number.value) + 1)
        elif pause.value:
            time.sleep(3)
            
total_duration=60          
thread = threading.Thread(target=counter, args=(number,pause,total_duration,))
thread.start()