Hello,
I would like to use interact with several widgets, FileChooser being one of them.
However, I realise that interact is not updated when I change the value of FileChooser.
Here is a basic example to illustrate:
from ipyfilechooser import FileChooser
import ipywidgets as widgets
from ipywidgets import interact
fc = FileChooser('/home')
def f(x):
return x
interact(f, x=fc)
In this example, the FileChooser is correctly displayed and works, however once a file is selected, it’s name is never displayed by the function f.
If I add a second widget, let’s say a slider, I can see that the function is called as expected when the slider is modified, but not when the FileChooser is updated.
from ipyfilechooser import FileChooser
import ipywidgets as widgets
from ipywidgets import interact
fc = FileChooser('/home')
def f(x,y):
return x,y
interact(f, x=fc, y=10)
Am I missing something to get this work?
Or is FileChooser simply not designed to work with interact?
I’m not sure why you are expecting something that is separate and that is made before ipywidgets was updated isn’t quite working hand in hand in the way you are expecting?
The ipyfilechooser has not been updated in four years as you can see here. Ipywidgets has been changed a lot in the last few years.
Thank you for your answer.
I know that ipyfilechooser has not been updated in four years, yet this does not necessarily means that it should no longer work.
Especially, I had seen that release 0.4.0 has included support for ValueWidget and get_interact_value() for compatibility with other widgets methods, and I expected this to be still working.
I also know about the file uploader widget, but the application i’m developing only needs a filename, not the content of the file to be uploaded. So, memory wise, if there is another solution than FileUpload, it would be better
Yes, I see it defines a value for get_interact_value(). But the fact that modifying the slider makes it work and it fails when modifying the FileChooser alone suggests something isn’t implemented by ipyfilechooser that slider modification signals to the interact() step.
" I had the same issue as you with ipywidgets and I found ipyfilechooser . Best thing is that it works well with interact_manual too."
Using that, I did find it works with interact_manual().
from ipyfilechooser import FileChooser
import ipywidgets as widgets
from ipywidgets import interact_manual
fc = FileChooser('/home')
def f(x):
return x
my_customized_interact_manual = interact_manual.options(manual_name="Click after selection")
my_customized_interact_manual(f, x=fc);
And even when the slider is added, it gets updated if you click the modified ‘Run Interact’ button after selecting your file:
from ipyfilechooser import FileChooser
import ipywidgets as widgets
from ipywidgets import interact_manual
fc = FileChooser('/home')
def f(x,y):
return x,y
my_customized_interact_manual = interact_manual.options(manual_name="Click after any update")
my_customized_interact_manual(f, x=fc, y=10);
So maybe it isn’t yet implemented for all the ipywidgets’ interactive styles?
See here for details on modifying the ‘Run Interact’/interact_manual() button text.
Great, thank you for this. Given that it works with interact_manual, but not with interact, I found that the difference comes from the observe method (which itself calls update) which is not implemented in FileChooser. I might give a try to add it.
Glad it helped track the difference.
If successful, you may want to at least file a pull request at the ipyfilechooser repo so others may at least use your version even if development doesn’t start back up.
I had a closer look to the FileUpload widget. As far as I understand, it is not possible to retrieve the path to the selected file from it. It is really dedicated to upload the file, without keeping track of the initial location of the file. So it really cannot be used as an alternative to ipyfilechooser.
When several widgets are used together in interactive context, another useful workaround that I found, and which works with the current version of ipyfilechooser (0.6.0), consists to use the register_callback function of filechooser, to call a function whose purpose is to “touch” another widget and trigger an observable event.
The advantage, as compared to the interact_manual method, is there is no need for a second click to validate a change of file.
Here is an example with an IntSlider as second widget
from ipyfilechooser import FileChooser
import ipywidgets as widgets
from ipywidgets import interact, interactive
# Define the widgets
fc = FileChooser('/home')
slider = widgets.IntSlider(value=0, min=0, max=10)
# Workaround function, to "touch" the slider value
# (it's value is left unchanged, but this trigger an observable event for interact)
def make_fc_interact(*args):
value = slider.value
slider.value = 0 if value > 0 else 1
slider.value = value
# Main function called by interact
def f(file, slider):
print("file is :",file)
print("integer =",slider)
# 2nd part of the workaround: call "register_callback" method of fc
fc.register_callback(make_fc_interact)
interact(f, file=fc, slider=slider)