title: Tkinter OptionMenu Portable Message Box
body: <p>I am trying to create a light weight cross platform Message Box that contains a list of items.  Ideally it has an API that allows you to pass in a message to to display, a title, and tuple of choices.  When pressing OK it would return the currently selected choice.  It would also be preferred that the required modules be part of the standard python distributions.</p>
  
  <p>Easygui has what I am looking for called a choicebox found at <a href="http://easygui.sourceforge.net/download/version0.95/tutorial/index.html#contents_item_10.1" rel="nofollow">http://easygui.sourceforge.net/download/version0.95/tutorial/index.html#contents_item_10.1</a>.  However the window it pops up is monstrous and it <em>always</em> sorts your list of choices alphabetically.  Because of these 'features', easygui is not ideal.</p>
  
  <p>I have also looked into bwidgets, pmw, and Tix.  While trying these I have come across a few issues including: difficultly finding working examples and failures across different platforms.</p>
  
  <p>My working model is using Tkinter's OptionMenu and pickle to return the data (see code samples below).  While this works, it is rather annoying having to save the choice to the file system to avoid using global variables.  <strong>Is there a way to return the selection upon destruction of the gui?</strong></p>
  
  <p>Any help / advice would be greatly appreciated.  Note that these examples are only for reference, they may or may not run properly on your system.  </p>
  
  <p><strong>State Management Module</strong></p>
  
  <pre><code>import pickle
  
  def store(pkl_path, data_to_store):
      try:
          fid = open(pkl_path, 'w')
          pickle.dump(data_to_store, fid)
      except:
          print 'Unable to store data in ' + pkl_path
      else:
          fid.close()
  
  def load(pkl_path):
      try:
          fid = open(pkl_path, 'r')
          loaded_state = pickle.load(fid)
          fid.close()
      except:
          loaded_state = None
      else:
          fid.close()
  
      return loaded_state
  </code></pre>
  
  <p><strong>Menu Module</strong></p>
  
  <pre><code>from Tkinter import *
  
  def Prompt_Dropdown_Ok_Cancel(title, options, pickle_file, default_selection=0):
      master = Tk()
      master.title(title)
  
      var = StringVar(master)
      var.set(options[default_selection]) # default value
  
      w = OptionMenu(master, var, *options)
      w.pack()
  
      def ok():
          state.store(pickle_file, var.get())
          master.quit()
  
      def cancel():
          state.store(pickle_file, None)
          master.quit()
  
      button = Button(master, text="OK", command=ok)
      button.pack()
      b2 = Button(master, text="Cancel", command=cancel)
      b2.pack()
  
      mainloop()
  </code></pre>
  
  <p><strong>Example Usage</strong></p>
  
  <pre><code>from menu_module import *
  
  def display_com_selection():
      pkl_path = '.tmp/comm_selection'
  
      title = 'COM Port Selection'
      Prompt_Dropdown_Ok_Cancel(title,get_available_com(),pkl_path)
  
      selection = state.load(pkl_path)
  
      return selection
  </code></pre>
  
  <p><strong>EDIT</strong></p>
  
  <p>Disregarding my concern about global variables, I tried an implementation using them to see if it was any easier.  It makes things substantially easier, however my question still stands for a better way to do this.</p>
  
  <p>Below is the reworked Menu Module</p>
  
  <pre><code>from Tkinter import *
  Prompt_Dropdown_Ok_Cancel_Selection = None
  
  def Prompt_Dropdown_Ok_Cancel(title, message, options, default_selection=0):
      master = Tk()
      master.title(title)
      var = StringVar(master)
      var.set(options[default_selection]) # default value
      l = Label(master, text=message)
      l.pack()
      w = OptionMenu(master, var, *options)
      w.pack(fill=BOTH, expand=1)
  
      def ok():
          global Prompt_Dropdown_Ok_Cancel_Selection
          Prompt_Dropdown_Ok_Cancel_Selection = str(var.get())
          master.destroy()
  
      def cancel():
          global Prompt_Dropdown_Ok_Cancel_Selection
          Prompt_Dropdown_Ok_Cancel_Selection = str(var.get())
          master.destroy()
  
      button = Button(master, text="OK", command=ok)
      button.pack(side=LEFT)
      b2 = Button(master, text="Cancel", command=cancel)
      b2.pack(side=LEFT)
  
      mainloop()
  
      return Prompt_Dropdown_Ok_Cancel_Selection
  </code></pre>