ipywidgets 按钮只能使用一次:多次使用同一个按钮

问题描述 投票:0回答:1

我有以下课程,我有 4 个按钮可以去:

  • 下一张图片
  • 上一张图片
  • 最后一张图
  • 第一张图

使用 jupyter notebook,我想点击所需的按钮,它会转到相关的图像。但是按钮只工作一次(同一个或另一个按钮),我无法浏览所有图像。

如何在这个类中多次使用按钮?

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):
        if not self.is_start():
            self.initialize()
        
    def initialize(self):
        self.index=0
        self.plot_restoration()    
    
    def go_left(self):
        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):
        if not self.is_end():
            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])
        
        # Launch of function when click
        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)

感谢您的帮助

button jupyter-notebook onclick display ipywidgets
1个回答
1
投票
  1. 传递方法引用而不是调用方法

  2. 向按钮的事件处理程序添加第二个参数,代表单击的按钮小部件实例。

  3. 你将需要一些其他的逻辑更新,但前两点应该足以涵盖如何多次使用按钮

    from ipywidgets import Button, HBox, Layout, VBox
    
    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, b): # <- 2. button argument
            if not self.is_start():
                self.initialize()
    
        def initialize(self):
            self.index=0
            self.plot_restoration()    
    
        def go_left(self, b): # <- 2. button argument
            if not self.is_displayed or self.is_start():
                self.initialize()
            else: 
                self.index -= 1
                self.plot_restoration()
    
        def go_right(self, b): # <- 2. button argument
            if not self.is_end():
                self.index += 1
                self.plot_restoration()
    
        def go_top_right(self, b): # <- 2. button argument
            if not self.is_end():
                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])
    
            # Launch of function when click
            button_1.on_click(self.go_top_left) # <- 1. method reference
            button_2.on_click(self.go_left) # <- 1. method reference
            button_3.on_click(self.go_right) # <- 1. method reference
            button_4.on_click(self.go_top_right) # <- 1. method reference
    
            display(self.box)
    
© www.soinside.com 2019 - 2024. All rights reserved.