Jupyter Notebook按钮控件循环等待用户输入问题求助
解决按钮控制循环迭代的问题
嘿,我完全懂你遇到的困扰——你想用两个按钮让用户选择,循环必须等用户点击其中一个按钮后才会进行下一次迭代。之前你参考的代码是基于监听控件属性变化的,但按钮的交互逻辑是点击事件,不是属性变更,所以得调整装饰器来适配按钮的工作方式。
问题核心
原来的yield_for_change函数是监听控件的某个属性(比如输入框的value)变化来触发生成器继续执行,但按钮没有这样的属性变化来触发,而是通过on_click事件响应交互,所以我们需要重写装饰器来处理点击事件,同时支持多个按钮。
完整解决方案代码
from functools import wraps from ipywidgets import Button, display def yield_for_button_clicks(*buttons): def decorator(iterator): @wraps(iterator) def inner(): gen = iterator() def on_click(_): try: # 发送信号让生成器继续执行 gen.send(None) except StopIteration: # 循环结束后,移除所有按钮的点击监听 for btn in buttons: btn.on_click(on_click, remove=True) # 给每个传入的按钮绑定点击事件 for btn in buttons: btn.on_click(on_click) # 启动生成器 next(gen) return inner return decorator # 创建两个选项按钮 button1 = Button(description="选择选项1") button2 = Button(description="选择选项2") # 显示按钮 display(button1, button2) @yield_for_button_clicks(button1, button2) def controlled_loop(): for i in range(10): print(f"完成第 {i+1} 轮准备,请点击任意按钮继续") # 暂停在这里,等待按钮点击 yield print(f"已收到点击,进入下一轮循环\n") # 启动受控循环 controlled_loop()
代码解释
装饰器
yield_for_button_clicks:- 接受任意数量的按钮作为参数,给每个按钮绑定点击事件处理函数
- 当按钮被点击时,会触发
on_click函数,给生成器发送信号,让它从yield处继续执行 - 当生成器抛出
StopIteration(循环结束),自动移除所有按钮的点击监听,避免内存泄漏
受控循环函数
controlled_loop:- 每次循环到
yield语句时会暂停执行,直到有按钮被点击 - 点击按钮后,生成器恢复执行,进入下一次循环迭代
- 每次循环到
这样就能实现你想要的效果:循环每一次迭代都等待用户点击两个按钮中的任意一个,点击后才继续下一步。
内容的提问来源于stack exchange,提问作者Любовь Пономарева
相关产品推荐
相关产品推荐

