Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
442 views
in Technique[技术] by (71.8m points)

ipywidgets - Python onclick button widget return object

I am trying to build a file/data selector in jupyter notebooks with python. The idea is that I select some files and data channels in the files with the multipleSelect widget and then with a button return a dataFrame.

How can I access the df_object?

#stack example
from ipywidgets import widgets
from IPython.display import display
from IPython.display import clear_output
import pandas as pd
import numpy as np
filenames = ["file1", "file2"]
file_dict = {
    "file1":pd.DataFrame(np.arange(5)),
    "file2":pd.DataFrame(np.arange(10,15))
}

def data_selection():
    sel_file = widgets.SelectMultiple(description="Files",
    options=filenames)
    display(sel_file)

    button = widgets.Button(description="OK")
    display(button)            

    def on_button_clicked(button):
        clear_output(wait=True) #clears the previous output
        display(sel_file) #displays new selection window
        display(button) #displays new button
        for f in sel_file.value:
            print (f)
            display (file_dict[f])
            #global df_object #would be a solution but not recommended for sure
            df_object = file_dict[f]
            return df_object #doesn't work
    button.on_click(on_button_clicked)

data_selection()    
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You really should be using a class for this, and then define all your functions as acting on an instance of that class. Not all of them need to be publicly accessible as well. You can also store the df_objects in a separate attribute like a dictionary and access the dictionary using a separate function. Check out the code below:

class foo(object):

    def __init__(self, file1, file2):
        self.filenames = [file1, file2]
        self.file_dict = {
                file1:pd.DataFrame(np.arange(5)),
                file2:pd.DataFrame(np.arange(10,15))
            }

    def _create_widgets(self):
        self.sel_file = widgets.SelectMultiple(description='Files',
                                               options=self.filenames,
                                               value=[self.filenames[0]],
                                              )
        self.button = widgets.Button(description="OK")
        self.button.on_click(self._on_button_clicked)

    def _on_button_clicked(self, change):
        self.out.clear_output()
        self.df_objects = {}
        with self.out:
            for f in self.sel_file.value:
                print(f)
                display(self.file_dict[f])
                self.df_objects[f] = self.file_dict[f]

    def display_widgets(self):
        self._create_widgets()
        self.out = widgets.Output()  # this is the output widget in which the df is displayed
        display(widgets.VBox(
                            [
                                self.sel_file,
                                self.button,
                                self.out
                            ]
                        )
               )

    def get_df_objects(self):
        return self.df_objects

Then you can create instances and display the widgets like so:

something = foo('a', 'b')
something.display_widgets()

something.get_df_objects() will return a dictionary with the required 'file:dataframe_of_file' key-value pairs.

Hope this helps :)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...