title: Nesting widgets in kivy
body: <p>I'm trying to make an interface in kivy and I think there are some fundamental things I don't understand about custom widgets and how to hierarchy them, even after going through the tutorial.  I think I have more of a box-model html mindset, so the way widgets are nested in native GUIs are still kind of foreign to me.</p>
  
  <p>Some background:</p>
  
  <ol>
  <li><p>I consulted <a href="http://kivy.org/docs/guide/widgets.html" rel="nofollow noreferrer">this entry</a> on how to add a background (It answers the question: "How to add a background image/color/video/... to a Layout", which I believe I was replicating with the _update_rect methods).</p></li>
  <li><p><a href="http://kivy.org/docs/guide/firstwidget.html" rel="nofollow noreferrer">This one</a> that has an on_touch_down event.</p></li>
  </ol>
  
  <p>K, I'm trying to get MyApp to look like this...</p>
  
  <p><img src="https://i.stack.imgur.com/yZuFq.png" alt="enter image description here"></p>
  
  <p>As I understand it, here are the things I'd need for that:</p>
  
  <ol>
  <li>You have an app.</li>
  <li>The app has a root.</li>
  <li>The root has a background, say the background is white.</li>
  <li>The background contains a holder, say the holder has a little margin from the background and is gray.  I do want this to be a widget rather than just a non-widget canvas because I want the holder to react to click events, as well.  It turns random colors when clicked. (Just to show it's doing something.)</li>
  <li>The holder contains two custom widgets.  These are circles with labels, each colored green.  They turn random colors when clicked (just to show they're doing something).</li>
  </ol>
  
  <p>Here's my code, which doesn't crash anymore, but doesn't display any colors or objects of any kind.</p>
  
  <pre><code>#!/usr/bin/kivy
  import kivy
  kivy.require('1.7.2')
  
  from random import random
  from kivy.app import App
  from kivy.uix.widget import Widget
  from kivy.uix.floatlayout import FloatLayout
  from kivy.graphics import Color, Ellipse, Rectangle
  
  class MyApp(App):
      title = 'My App'
      def build(self):
          root = RootWidget()
          root.bind(
              size=self._update_rect,
              pos=self._update_rect)
      def _update_rect(self, instance, value):
          self.rect.pos = instance.pos
          self.rect.size = instance.size
  
  class RootWidget(FloatLayout):
      def __init__(self, **kwargs):
          super(RootWidget, self).__init__(**kwargs)
          with self.canvas.before:
              Color(1, 0, 0, 1) # This RED does not display.
              self.rect = Rectangle(
                                      size=self.size,
                                      pos=self.pos,
                                      text="some junk!")  # This label does not display.
          mybackground = Background()
          self.add_widget(mybackground)
      def _update_rect(self, instance, value):
          self.rect.pos = instance.pos
          self.rect.size = instance.size
  
  class Background(Widget):
      def __init__(self, **kwargs):
          super(Background, self).__init__(**kwargs)
          with self.canvas.before:    
              Color(1, 1, 1, 1)       # This WHITE does not display
              self.rect = Rectangle(
                                      size=self.size,
                                      pos=self.pos,
                                      text="More stuff!")  # This label does not display.
          myholder = Holder()
          self.add_widget(myholder)
      def _update_rect(self, instance, value):
          self.rect.pos = instance.pos
          self.rect.size = instance.size
  
  class Holder(Widget):
      def __init__(self, **kwargs):
          super(Holder, self).__init__(**kwargs)
          with self.canvas.before:    
              Color(0.25, 0.25, 0.25, 1) # This GRAY does not display
              self.rect = Rectangle(
                                      size=self.size,
                                      pos=self.pos,
                                      text="More stuff!")  # This does not display.
          c1 = Circley(label="Label 1")  # I see I'd need to do some size/pos math here to center
          c2 = Circley(label="Label 2")  # but since everything isn't working, I've tabled this.
          self.add_widget(c1)
          self.add_widget(c2)
      def _update_rect(self, instance, value):
          self.rect.pos = instance.pos
          self.rect.size = instance.size
      def on_touch_down(self, touch):
          rcolor = Color(random(), random(), random(), 1)
          with self.canvas:
              self.color = rcolor
  
  class Circley(Widget):
      def __init__(self, label='label', **kwargs):
          super(Circley, self).__init__(**kwargs)
          with self.canvas.before:    
              Color(0, 1, 0, 1) # This GREEN does not display
              self.circ = Ellipse(
                          size=self.size,
                          pos=self.pos,
                          text=label
              )
      def _update_circ(self, instance, value):
          self.circ.pos = instance.pos
          self.circ.size = instance.size
      def on_touch_down(self, touch):
          rcolor = Color(random(), random(), random(), 1)
          with self.canvas:
              self.color = rcolor
  
  if __name__ == '__main__':
      MyApp().run()
  </code></pre>
  
  <p>Any pointers on what I'm doing wrong and how to nest these widgets correctly?</p>