You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

代码解释

  1. 装饰器yield_for_button_clicks:

    • 接受任意数量的按钮作为参数,给每个按钮绑定点击事件处理函数
    • 当按钮被点击时,会触发on_click函数,给生成器发送信号,让它从yield处继续执行
    • 当生成器抛出StopIteration(循环结束),自动移除所有按钮的点击监听,避免内存泄漏
  2. 受控循环函数controlled_loop:

    • 每次循环到yield语句时会暂停执行,直到有按钮被点击
    • 点击按钮后,生成器恢复执行,进入下一次循环迭代

这样就能实现你想要的效果:循环每一次迭代都等待用户点击两个按钮中的任意一个,点击后才继续下一步。

内容的提问来源于stack exchange,提问作者Любовь Пономарева

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 06:29:12