title: Pass data frame through Tkinter classes
body: <p>I am using Python 2.7 and Tkinter. I am almost new to Object Oriented programs. I have a long program with many Tkinter windows and at some point I ask the user to load an Excel file that I read with Pandas, and want to permanently use and update that value (of a <em>data</em> variable). The way that I am doing it now is with global variables but I know that it is dangerous, inefficient and not elegant at all.</p>
  
  <p>Even though I could do controller.show_frame(framename) given the way my gui class is built, I ended up building some of the frames myself just so the data variable would update itself.</p>
  
  <p>I read and tried some answers in Stack Overflow but may have implemented them wrong:</p>
  
  <ul>
  <li>Tried creating a dictionary inside the gui class, something like <code>self.app_data = {data=[],filename=""}</code> and updating it from other windows, the thing here is that I think that the class gui is instanced only once and it kind of creates all of the other window classes so this did not work. Maybe I did something wrong there. (not shown on the code).</li>
  <li>Tried to do something as what was suggested <a href="https://stackoverflow.com/questions/31394152/pass-variables-values-from-one-frame-to-another-tkinter-python">here</a> but I could just not make it work. </li>
  </ul>
  
  <p>Main frame is some sort of intermediate step that I need for other purposes; the following code is a simplification of my program.</p>
  
  <p>I know this is an awful nightmare code! Thank you :)</p>
  
  <pre><code>import Tkinter as tk
  import pandas as pd 
  import tkFileDialog
  import tkMessageBox
  global data, strat_columns, filename
  data = pd.DataFrame([])
  strat_columns = []
  filename = ""
  
  class gui(tk.Tk):
  
      data = pd.DataFrame([])
      filename = ""
      def __init__(self):
          tk.Tk.__init__(self)
          container = tk.Frame(self)
          container.pack(side="top",fill="both",expand=True)
          self.frames = {}
  
          for F in (main_frame, first_frame):
              frame = F(container, self)
              self.frames[F] = frame
              frame.grid(row=0, column=0, sticky="nsew")
          self.show_frame(main_frame)
  
      def show_frame(self,sel_frame):
          frame = self.frames[sel_frame]
          frame.tkraise()
  
      def get_page(self, page_class):
          return self.frames[page_class]
  
  
  class main_frame(tk.Frame):
  
      def __init__(self,parent,controller):
  
          tk.Frame.__init__(self,parent)
          self.parent = parent 
          self.controller = controller
          button_new = tk.Button(self,
                             text="New window",
                             command=lambda: self.button_new_callback())
          button_new.pack()
  
      def button_new_callback(self,*args,**kwargs):
          self.controller.show_frame(first_frame)
  
  
  class first_frame(tk.Frame):
  
      def __init__(self,parent,controller):
          tk.Frame.__init__(self,parent)
          self.controller = controller
          self.parent = parent
          self.show_frame = controller.show_frame
          statusText.set("Press Browse button and browse for file, then press the Go button")
          label = tk.Label(self, text="Please load a file: ")
          label.pack()
          entry = tk.Entry(self, width=50)
          entry.pack()
          button_go = tk.Button(self,
                             text="Go",
                             command=lambda: self.button_go_callback(entry,statusText,message))
          button_browse = tk.Button(self,
                                 text="Browse",
                                 command=lambda: self.button_browse_callback(entry))
          button_go.pack()
          button_browse.pack()
          message = tk.Label(self, textvariable=statusText)
          message.pack()
  
      def button_browse_callback(self,entry):
          global filename
          filename = tkFileDialog.askopenfilename()
          entry.delete(0, tk.END)
          entry.insert(0, filename)
  
      def button_go_callback(self,entry,statusText,message):
          global data
          input_file = entry.get()
          data = pd.read_excel(filename)
          sf = second_frame(self.parent, self)
          sf.grid(row=0, column=0, sticky="nsew")
          sf.tkraise()
  
  class second_frame(tk.Frame):
       pass
  
  if __name__ == "__main__":
  
      my_gui = gui()
      my_gui.mainloop()
      my_gui.title("TEST")
  </code></pre>