title: Python Tkinter Scrollable Frame Class?
body: <p>I would like to make a <code>Tkinter</code> <code>class</code>, based on <a href="https://stackoverflow.com/a/1884142/901641">the answer here</a>, which is a <code>Frame</code> that automatically shows/hides <code>Scrollbar</code>s around the content as necessary.</p>
  
  <p>The answer that I linked to above works perfectly for my needs, with the caveat that because it's not contained within a <code>class</code>, it's not reusable. I figured this would be pretty quick and easy, but for some reason, my <code>AutoScrollbar</code>s never appear once I refactor the code into its own <code>class</code>, regardless of how much or little of the contents of the <code>Frame</code> is hidden by the window resizing.</p>
  
  <pre><code># This class is unchanged from the other answer that I linked to,
  # but I'll reproduce its source code below for convenience.
  from autoScrollbar import AutoScrollbar
  from Tkinter       import Button, Canvas, Frame, HORIZONTAL, Tk, VERTICAL
  
  # This is the class I made - something isn't right with it.
  class AutoScrollable(Frame):
      def __init__(self, top, *args, **kwargs):
          Frame.__init__(self, top, *args, **kwargs)
  
          hscrollbar = AutoScrollbar(self, orient = HORIZONTAL)
          hscrollbar.grid(row = 1, column = 0, sticky = 'ew')
  
          vscrollbar = AutoScrollbar(self, orient = VERTICAL)
          vscrollbar.grid(row = 0, column = 1, sticky = 'ns')
  
          canvas = Canvas(self, xscrollcommand = hscrollbar.set,
                                yscrollcommand = vscrollbar.set)
          canvas.grid(row = 0, column = 0, sticky = 'nsew')
  
          hscrollbar.config(command = canvas.xview)
          vscrollbar.config(command = canvas.yview)
  
          # Make the canvas expandable
          self.grid_rowconfigure(0, weight = 1)
          self.grid_columnconfigure(0, weight = 1)
  
          # Create the canvas contents
          self.frame = Frame(canvas)
          self.frame.rowconfigure(1, weight = 1)
          self.frame.columnconfigure(1, weight = 1)
  
          canvas.create_window(0, 0, window = self.frame, anchor = 'nw')
          canvas.config(scrollregion = canvas.bbox('all'))
  
  # This is an example of using my new class I defined above.
  # It's how I know my class isn't working quite right.
  root = Tk()
  autoScrollable = AutoScrollable(root)
  autoScrollable.grid(row = 0, column = 0, sticky = 'news')
  root.rowconfigure(0, weight = 1)
  root.columnconfigure(0, weight = 1)
  
  for i in xrange(10):
      for j in xrange(10):
          button = Button(autoScrollable.frame, text = '%d, %d' % (i, j))
          button.grid(row = i, column = j, sticky = 'news')
  
  autoScrollable.frame.update_idletasks()
  
  root.mainloop()
  </code></pre>
  
  <p>Here's the source for <code>autoScrollbar</code>, which I'm including because I import it in the above source, but I don't think the actual problem is here.</p>
  
  <pre><code># Adapted from here: http://effbot.org/zone/tkinter-autoscrollbar.htm
  
  from Tkinter import Scrollbar
  
  class AutoScrollbar(Scrollbar):
      '''
      A scrollbar that hides itself if it's not needed. 
      Only works if you use the grid geometry manager.
      '''
      def set(self, lo, hi):
          if float(lo) &lt;= 0.0 and float(hi) &gt;= 1.0:
              self.grid_remove()
          else:
              self.grid()
          Scrollbar.set(self, lo, hi)
  
      def pack(self, *args, **kwargs):
          raise TclError('Cannot use pack with this widget.')
  
      def place(self, *args, **kwargs):
          raise TclError('Cannot use pack with this widget.')
  </code></pre>