title: How to save ipywidget output and link it to a button to run another function with saved inputs
body: <p>This is going to be a kind of long question so I'll try to break it down as much as I can so please bear with me. My idea is to create an jupyter notebook app using jupyter widgets. My app will get some information using an API but it needs some inputs first which are time and entity name that also have some metadata. Because I have different ipywidgets incorporated here (SelectMultiple,2 Date pickers widgets (start, end) and button that would finally will load the function to get the data from the database.)</p>
  <p>Currently my widgets look like this:</p>
  <p><a href="https://i.stack.imgur.com/cOSIB.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/cOSIB.png" alt="enter image description here" /></a></p>
  <p>I'm able to obtain multiple entities ('Wells') (with its own metadata and assign an start and end date and save it in a dictionary). I have created a button but I'm having a hard time to be able to link the button to the already saved data to run my function everytime I run click in 'run'. Here's my code:</p>
  <pre><code>#I created a class to add multiple widgets
  class SelectMutipleInteract(widgets.HBox):
          
      def __init__(self,api_obj):
          #In my init function I'm obtaining all the entities to be stored in the Selectmultiple widget
          env='prod'
          pre_df = api_obj.search_sites_by_name('',env).set_index('site_id').sort_index(ascending=True)
          pre_df = pre_df[pre_df['db'].str.contains('jon')]
          self.pre_df = pre_df
          
          self.w = widgets.SelectMultiple(
              options = pre_df.name.values,
              rows = len(pre_df),
              description = 'Wells',
              disabled = False)
          #From that same data I get initial start and end dates (which I'll be able to change based on the time I want)
          try:
              self.start_date = datetime.strptime(self.pre_df.sort_values(by='date_created')['date_created'].values[0],'%Y-%m-%dT%H:%M:%SZ')
              self.start_date = pd.Series(self.start_date).dt.round('H')[0]
          except:
              'TypeError'
          
          try:
              self.start_date = datetime.strptime(self.pre_df.sort_values(by='date_created')['date_created'].values[0],'%Y-%m-%dT%H:%M:%S.%fZ') 
              self.start_date = pd.Series(self.start_date).dt.round('H')[0]
          except:
              'TypeError'
          
          try:
              self.end_date = datetime.strptime(self.pre_df.sort_values(by='last_transmission',ascending=False)['last_transmission'].values[0],'%Y-%m-%dT%H:%M:%SZ')
              self.end_date = pd.Series(self.end_date).dt.round('H')[0]
          except:
              'TypeError'
              
          try:
              self.end_date = datetime.strptime(self.pre_df.sort_values(by='last_transmission',ascending=False)['last_transmission'].values[0],'%Y-%m-%dT%H:%M:%S.%fZ')
              self.end_date = pd.Series(self.end_date).dt.round('H')[0]
          except:
              'TypeError'
  
          # I created the rest of the widgets
          self.w1 = widgets.DatePicker(
                      description='Pick Start Date',
                      value = self.start_date)
          
          self.w2 = widgets.DatePicker(
                      description='Pick End Date',
                      value=self.end_date)
          
          self.w3 = widgets.Button(
                      description='Run',
                      button_style='info')
          
          self.selectors = [self.w,self.w1,self.w2,self.w3]
          
          #I think this as a super class and then each object to be assigned together
          super().__init__(children=self.selectors)
          self._set_observes()
          
      def _set_observes(self):
          self.selectors1 = self.selectors[:3]
          for widg in self.selectors1:
              widg.observe(self._observed_function_widgets1, names='value')
              
      #Observed function will work as the place to store the metadata        
      def _observed_function_widgets1(self,widg):
          self.dict = {}
          self.list_a = []
          
          for widg in self.selectors1:
              if type(widg.get_interact_value())==tuple:
                  self.list_a.append(widg.get_interact_value())
              else:
                  self.list_a.append(datetime.strftime(widg.get_interact_value(), '%Y-%m-%d %H:%M:%S'))
                  
          for well in self.list_a[0]:
              a = self.pre_df.loc[self.pre_df['name']==well,:]
              self.dict[well]= {'domain':a['db'],'site_slug':a['slug'],'start_date':self.list_a[1],
                                  'end_date':self.list_a[2]}
          
          print(self.dict)
          
          #This is where I put the connection of the button but I'm getting an error
          self.w3.on_click(self._on_button_clicked(self.dict))
          
          
      def _on_button_clicked(self,dict1):
          #Here I should run the final function
          print(1)
          print(dict1)
          
          
  SelectMutipleInteract(api_obj)
  </code></pre>
  <p>The error that I get when I press the button (after I already selected entities and times) is</p>
  <pre><code>{'SHB 67-34': {'domain': site_id
  183    jonah-energy
  Name: db, dtype: object, 'site_slug': site_id
  183    10004-24
  Name: slug, dtype: object, 'start_date': '2019-09-26 15:00:00', 'end_date': '2020-12-17 21:00:00'}, 'SHB 75-34': {'domain': site_id
  184    jonah-energy
  Name: db, dtype: object, 'site_slug': site_id
  184    10005-40
  Name: slug, dtype: object, 'start_date': '2019-09-26 15:00:00', 'end_date': '2020-12-17 21:00:00'}, 'SHB 77-34': {'domain': site_id
  185    jonah-energy
  Name: db, dtype: object, 'site_slug': site_id
  185    10006-46
  Name: slug, dtype: object, 'start_date': '2019-09-26 15:00:00', 'end_date': '2020-12-17 21:00:00'}}
  ---------------------------------------------------------------------------
  TypeError                                 Traceback (most recent call last)
  TypeError: 'NoneType' object is not callable
  </code></pre>
  <p>The whole idea is to (once the data has been selected and stored) then run the final function but I'm having a hard time conceptualize the creation on the button give that you need to run the several widgets first to get the data and store it and then click the button to run the function with that data they way I'm creating the widgets layout together.</p>
  <p>Any help would really appreciate it.</p>