Problem with button and textbox in jupyter with ipywidgets - python

I am trying to initialize a variable with the text contained in a textbox when the button is pressed , in a jupyter notebook running python 3. However it seems that I can't access the value in the textbox during the button pressing event and store it for later.
Here is the code :
import ipywidgets as widgets
from IPython.display import display
button = widgets.Button(description="Click Me!")
inp = widgets.Text(description='Path:')
Box = widgets.HBox([button,inp])
def on_button_clicked(b):
return inp.value
path = button.on_click(on_button_clicked)
display(Box
)
Any help would be greatly appreciated.Thanks in advance

The button.on_click function returns None. It doesn't return the value of the function you pass in as an argument. Think of on_click as connecting the button to a function that has side effects. In the example below I use it to append to a list.
import ipywidgets as widgets
from IPython.display import display
button = widgets.Button(description="Click Me!")
inp = widgets.Text(description='text:')
Box = widgets.HBox([button,inp])
value_list = []
def on_button_clicked(b):
value_list.append(inp.value)
print(value_list)
button.on_click(on_button_clicked)
Box

Your value will be available through
inp.value
Please see the documentation

Related

python ipywidgets button clicked with CONTROL combination

The typical way to create a button in python with widgets is as follows:
button = wd.Button(description = "Click")
output = wd.Output()
display(button, output)
def on_button_clicked(b):
with output:
print("button clicked")
button.on_click(on_button_clicked)
when clicking the button the corresponding method runs.
Is it possible to distinguish between simply click and CTRL+click?
i.e. having like two methods,on_click, or on_CTRL_click
thanks

With ipywidgets, how to close the tab containing the button that is pressed?

With Jupyter notebook and ipywidgets, I created a list of tabs, each tab contains a button.
I would like that when a button is pressed, it closes its tab, leaving the rest of the abs untouched.
I have tried the following but it does not work as the function close_on_click is always associated to the last tab.
import ipywidgets as widgets
from ipywidgets import HBox, VBox
import numpy
import matplotlib.pyplot as plt
from IPython.display import display
%matplotlib inline
tabs = []
for k in range(10):
wg_name = widgets.Text(
value=str(k),
placeholder='Index',
description='Name:',
disabled=False
)
wg_close = widgets.Button(
description='Close tab',
)
tabs.append(VBox(children=[wg_name, wg_delete]))
#wg_close.on_click
def close_on_click(b):
tab[k].close()
main_tab = widgets.Tab(children=tabs)
for k in range(10):
main_tab.set_title(k, str(k))
main_wg = VBox(children=[main_tab])
display(main_wg)
In your code you are closing tab[k], where k=9 since the loop has already finished when you call close_on_click. That's why only the last tab is closing.
To close the current tab you should use k = main_tab.selected_index like so:
def close_on_click(b):
tabs[main_tab.selected_index].close()
tabs.pop(main_tab.selected_index)
This is closing the current tab and removing it from the list of tabs, so that the next index will be correct.

How to create a jupyterhub widget as an object?

Using jupyterlab 1.1.4 I want to create an object that displays a widget and that simplifies the definition of the widgets and callback functions. In a first cell I create and start the instance:
from ipywidgets import FileUpload
from ipywidgets import widgets
from IPython.display import display
class MyWidget():
def __init__(self):
self.output = widgets.Output()
self.upload = FileUpload(description='Choose file')
self.upload_filename = None
self.upload.observe(self.upload_file, names=['value'])
display(self.upload, self.output)
#output.capture()
def upload_file(self, args):
self.upload_filename = list(args['new'].keys())[0]
print("File selected: {}".format(self.upload_filename))
w = MyWidget()
When running this cell it shows a FileUpload button, and when I click on it I can choose a file. But when I do so, I expect to see some output (as I print the selected filename). But there is no output.
What am I doing wrong? How to do it correctly?
I even can go farther and change the upload_file method like the following:
#output.capture()
def upload_file(self, args):
a=1/0
self.upload_filename = list(args['new'].keys())[0]
print("File selected: {}".format(self.upload_filename))
which contains an obvious error! But when I run the cell and choose a file, I do not see any error output.
How to fix this?

How to create a simple Button with output in a python jupyter notebook?

Trying to create a simple button with some output I tried the following code
from IPython.display import display
def clicked():
print("button has been clicked!")
button_download = widgets.Button(description = 'Test Button')
button_download.on_click(clicked)
display(button_download)
but when I click on the button I cannot see any output.
I found another example that works, but this is way too complicated:
from IPython.display import display
button = widgets.Button(description="Click Me!")
output = widgets.Output()
display(button, output)
def on_button_clicked(b):
with output:
print("Button clicked.")
button.on_click(on_button_clicked)
Do I really need to output thing so I can see the output of a print statement when I click the button?
The system is Jupyterlab 1.1.4.
You only need to add an argument to the clicked function to make it work:
from IPython.display import display
import ipywidgets as widgets
def clicked(arg):
print("button has been clicked!")
button_download = widgets.Button(description = 'Test Button')
button_download.on_click(clicked)
display(button_download)

Tkinter: clicking buttons in menu is triggering function with wrong argument

Hi,
Im struggling with strange for me error, so I want to have buttons in cascade menu, and each of them should trigger function, passing they name to it.
The code is as follows:
from tkinter import *
def say_hi(name):
print(name)
root = Tk()
menu = Menu(root)
root.config(menu=menu)
subjects_menu = Menu(menu)
menu.add_cascade(label="Subjects", menu=subjects_menu)
d = ["name1", "name2"]
for name in d:
subjects_menu.add_command(label=name, command=lambda:say_hi(name))
'''
this is also not working
name = "Math"
subjects_menu.add_command(label=name, command=lambda:say_hi(name))
name = "Physics"
subjects_menu.add_command(label=name, command=lambda:say_hi(name))
'''
root.mainloop()
So I want to print name of clicked button in console, and add buttons by iteration, not one by one (I cannot predict number of them)
After running program I get no errors, and window shows. Whichever button I click, console prints "name2".
I did add few more names - it always prints name of the last option.
Thanks in advance
Another (IMO neater) way to do this is to use functools.partial:
from functools import partial
for name in d:
subjects_menu.add_command(label=name, command=partial(say_hi, name))
Lambdas are tricky, but you can do what you want to do with a lambda argument:
for name in d:
subjects_menu.add_command(label=name, command=lambda x=name:say_hi(x))
This should solve your problem.

Categories

Resources