ipywidgets button only works once: use the same button multiple times

huangapple go评论63阅读模式
英文:

ipywidgets button only works once: use the same button multiple times

问题

I can help you translate the code comments and variable names. Here's the translated code:

我有以下类有4个按钮可用
- 下一张图片
- 上一张图片
- 最后一张图片
- 第一张图片

**jupyter notebook**我想点击所需的按钮以跳转到关联的图片但是按钮**只能点击一次**相同的或另一个按钮),我无法浏览所有图片

如何使这个类中的按钮可以多次使用

```python
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):
        # 定义按钮
        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)

Please note that the comments and variable names are translated, but the code itself remains in its original form.

英文:

I have the following class and I have 4 buttons to go to:

  • the next image
  • the previous image
  • the last image
  • the first image

Working with jupyter notebook, I want to click on the required button, which goes to the associated image. But the button only works once (the same or another button) and I can't go through all images.

How can I do to use buttons multiple times with this class?

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 &lt; 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 = [&#39;⇤&#39;, &#39;←&#39;, &#39;→&#39;, &#39;⇥&#39;]
layout = widgets.Layout(width=&#39;auto&#39;, height=&#39;auto&#39;)
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)

Thanks for your help

答案1

得分: 1

  1. 传递方法引用而不是调用方法
  2. 为按钮的事件处理程序添加第二个参数,表示点击的按钮小部件实例。
  3. 您将需要一些其他逻辑更新,但前两点应足够涵盖如何多次使用按钮。
英文:
  1. Pass the method reference instead of calling the method

  2. Add a 2nd argument to the buttons' event handlers, representing the clicked button widget instance.

  3. You are going to need to some other logic updates, but the first two points should cover enough how to use the buttons multiple times

    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 &lt; 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): # &lt;- 2. button argument
            if not self.is_start():
                self.initialize()
    
        def initialize(self):
            self.index=0
            self.plot_restoration()    
    
        def go_left(self, b): # &lt;- 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): # &lt;- 2. button argument
            if not self.is_end():
                self.index += 1
                self.plot_restoration()
    
        def go_top_right(self, b): # &lt;- 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 = [&#39;⇤&#39;, &#39;←&#39;, &#39;→&#39;, &#39;⇥&#39;]
            layout = widgets.Layout(width=&#39;auto&#39;, height=&#39;auto&#39;)
            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) # &lt;- 1. method reference
            button_2.on_click(self.go_left) # &lt;- 1. method reference
            button_3.on_click(self.go_right) # &lt;- 1. method reference
            button_4.on_click(self.go_top_right) # &lt;- 1. method reference
    
            display(self.box)
    

huangapple
  • 本文由 发表于 2023年4月13日 16:45:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/76003430.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定