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

Jupyter Notebook中ipywidgets按钮仅能点击一次,如何实现重复使用?

问题修复:实现Jupyter按钮重复点击遍历图片

你的代码核心问题出在按钮回调绑定方式错误,同时还有几处逻辑判断的小问题,导致按钮只能触发一次。以下是具体修复方案:

1. 按钮回调绑定错误(最关键)

在set_buttons方法中,你给on_click传递的是方法执行后的结果(加了括号()),而不是方法本身。这会导致程序初始化时就执行一次方法,后续点击按钮时没有实际回调函数可以触发。

错误写法:

button_1.on_click(self.go_top_left())

正确写法(去掉括号,传递函数对象):

button_1.on_click(self.go_top_left)

2. 方法调用遗漏括号

is_displayed是一个方法,但在go_left中你直接用了self.is_displayed(没有加括号调用),导致判断的是方法对象而非返回的布尔值,逻辑出错。

错误写法:

if not self.is_displayed or self.is_start():

正确写法:

if not self.is_displayed() or self.is_start():

3. 按钮逻辑优化

  • go_top_left:当前逻辑是只有不在第一张时才跳转,改为点击就直接跳转到第一张,无需判断位置
  • go_top_right:当前逻辑是只有不在最后一张时才跳转,改为点击就直接跳转到最后一张,无需判断位置

完整修改后的代码

class DisplayButtons:
    
    def __init__(self, low_path, restored_path):
        self.left = None
        self.right = None
        self.top_right = None
        self.top_left = None
        self.index = None
        self.box = None
        self.low_path = low_path
        self.restored_path = restored_path
        
    def plot_restoration(self):
        clear_output()
        display(self.box)

        img = imread(self.low_path[self.index])
        if img.ndim == 3: img = img[0]
        height, width = img.shape
        if height < 450: height, width = height * 2, width * 2
        img_restored = imread(self.restored_path[self.index])
        plt.figure(figsize = (height/50, width/50))
        plt.subplot(1, 2, 1)
        plt.imshow(img)
        plt.subplot(1, 2, 2)
        plt.imshow(img_restored)
        plt.show()
        
    def is_end(self):
        return self.index == len(self.low_path) - 1
    
    def is_start(self):
        return self.index == 0
    
    def is_displayed(self):
        return self.index is not None
        
    def go_top_left(self):
        # 点击直接跳转到第一张,无需判断当前位置
        self.initialize()
        
    def initialize(self):
        self.index=0
        self.plot_restoration()    
    
    def go_left(self):
        # 修复is_displayed的调用方式,加括号
        if not self.is_displayed() or self.is_start():
            self.initialize()
        else: 
            self.index -= 1
            self.plot_restoration()

    def go_right(self):
        if not self.is_end():
            self.index += 1
            self.plot_restoration()

    def go_top_right(self):
        # 点击直接跳转到最后一张,无需判断当前位置
        self.index = len(self.low_path) - 1
        self.plot_restoration()
            
    def set_buttons(self):
        # Define buttons
        scroll = ['⇤', '←', '→', '⇥']
        layout = widgets.Layout(width='auto', height='auto')
        buttons = [Button(description=s, layout = layout) for s in scroll]
        button_1, button_2, button_3, button_4 = buttons

        box_1 = VBox([buttons[0]])
        box_2 = VBox([buttons[1]])
        box_3 = VBox([buttons[2]])
        box_4 = VBox([buttons[3]])
        self.box = HBox([box_1, box_2, box_3, box_4])
        
        # 修复按钮回调绑定:去掉方法后的括号,传递函数对象
        button_1.on_click(self.go_top_left)
        button_2.on_click(self.go_left)
        button_3.on_click(self.go_right)
        button_4.on_click(self.go_top_right)
        
        display(self.box)

使用说明

修改后,按钮可以重复点击,正常遍历所有图片:

  • 点击⇤直接回到第一张
  • 点击←回到上一张(当前是第一张时会重新显示第一张)
  • 点击→前进到下一张(当前是最后一张时无动作)
  • 点击⇥直接跳转到最后一张

内容的提问来源于stack exchange,提问作者salomepx

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 09:33:19