1

I am trying to make an input widget for a module i have made (see this SO question).

The input widget should have a title bar and a variable number of input lines below. I had in mind to have an delete button at the end of each input line.

The delete button should ideally delete the container widget and all the children widgets, but hiding the container widget and children would also be acceptable.

I have not been able to find a useful recipe to this problem.

Currently i got this code, but i have no clue less as how to solve the problem.

import ipywidgets as w
​
def add_btn_clicked(b):
    input_box.children = (input_box.children[0], line()) + input_box.children[1:]
​
def delete_btn_clicked(b):
    # ???
    with output:
        print(b.keys)
    return None

add = w.Button(icon="plus-circle")
add.on_click(add_btn_clicked)
​
title = w.HBox([w.Label(value=str(i)) for i in range(3)]+[add])
​
def line():
    delete = w.Button(icon="trash")
    delete.on_click(delete_btn_clicked)
    return w.HBox([w.FloatText(value=i) for i in range(3)]+[delete])
​
input_box = w.VBox([title,line()])
output = w.Output()
​
display(input_box)
display(output)

Is there a way to tell what the parent element is from the button click or another way to achieve what I am attempting?

Kim Petersen
  • 199
  • 1
  • 7

1 Answers1

2

You can create the widgets and container separately, then define the .parent attribute on the children as the container, before assembling together. That way you can effectively hide the container when the button is clicked (with .parent.layout.display = 'none').

import ipywidgets as w

def add_btn_clicked(b):
    input_box.children = (input_box.children[0], line()) + input_box.children[1:]

def delete_btn_clicked(b):
    b.parent.layout.display = 'none'

add = w.Button(icon="plus-circle")
add.on_click(add_btn_clicked)

title = w.HBox([w.Label(value=str(i)) for i in range(3)]+[add])

def line():
    delete = w.Button(icon="trash")
    delete.on_click(delete_btn_clicked)
    val_widgets = [w.FloatText(value=i) for i in range(3)]
    container = w.HBox()
    delete.parent = container
    for widg in val_widgets:
        widg.parent = container
    children = val_widgets + [delete]
    container.children = children
    return container

input_box = w.VBox([title,line()])
output = w.Output()

display(input_box)
display(output)
ac24
  • 5,325
  • 1
  • 16
  • 31