使用线程定期更新的 Ipywidget

Posted

技术标签:

【中文标题】使用线程定期更新的 Ipywidget【英文标题】:Ipywidget with periodic update using thread 【发布时间】:2022-01-15 14:37:19 【问题描述】:

我正在尝试定期记录滑块小部件的值。我已经在Asynchronous Widgets 上查看了官方文档。但是对于我的代码,阻塞似乎仍然发生。

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

我希望在拖动滑块时每秒输出一次滑块值。相反,它只在拖动过程中打印 0。

我也尝试将两个进程都放在线程中(并使用滑块的观察方法),但效果不佳。

环境:Jupyter 实验室 3.2.1

【问题讨论】:

【参考方案1】:

问题来自在代码末尾调用join 函数。在您的线程上调用join 会阻止您的小部件更新。我还将您的小部件w 和您的输出out 作为参数传递给您的`record 函数(如here)。所以总的来说,代码看起来像这样:

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

下面是一个输出示例:

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

【讨论】:

感谢您的解决方案。是的,我意识到 join() 是导致问题的原因。此外,“with out: print()”对我不起作用,但 out.append_stdout() 可以。不过我不知道原因。

以上是关于使用线程定期更新的 Ipywidget的主要内容,如果未能解决你的问题,请参考以下文章

将ipywidget按钮对齐到中心

关于使用多线程定期强制检查软件更新的问题

为啥loop之后就可以子线程更新ui

使用不同的线程更新 GUI (WPF)

为啥使用多线程更新数组没有加速

ios开发在子线程更新ui会怎样