Kivy canvas.before Renders on Top of Children Widgets
<p>I'm developing a kivy application with custom widgets in a TabbedPanel. The custom widgets have the ability to specify a background color through drawing on canvas.before and are specified in Python code, not a kv file.</p>

<p>When the application renders the tabs the background color Rectangle is drawn on top of the widgets on the custom control. How do I make the background color Rectangle render under the children widgets?</p>

<pre><code>#: kivy_mixins.py
from kivy.graphics import Color, Rectangle
from kivy.properties import ListProperty

class BackgroundColorMixin( object ):
   def __init__( self, *args, **kwargs ):
      self.bind( bg_color = self._set_bg_color )
      super( BackgroundColorMixin, self ).__init__( *args, **kwargs )

      self._initialized = False

   def _initialize( self, initial_color ):
      self._color = initial_color
      self._background_rectangle = Rectangle( size = self.size, pos = self.pos )

      self.canvas.before.add( self._color )
      self.canvas.before.add( self._background_rectangle )
      self.bind( size = self._update_bg_color, pos = self._update_bg_color )

      self._initialized = True

   def _set_bg_color( self, instance, value ):
      color_components = len( value )

      if color_components == 3:
         color = Color( value[ 0 ], value[ 1 ], value[ 2 ] )
      elif color_components == 4:
         color = Color( value[ 0 ], value[ 1 ], value[ 2 ], value[ 3 ] )
      else:
         raise Exception( "Invalid color: {}".format( str( value ) ) )

      if not self._initialized:
         self._initialize( color )
      else:
         self.canvas.before.clear()

         self._color = color
         self._background_rectangle = Rectangle( size = self.size, pos = self.pos )

         self.canvas.before.add( self._color )
         self.canvas.before.add( self._background_rectangle )

   def _update_bg_color( self, instance, value ):
      self._background_rectangle.pos = instance.pos
      self._background_rectangle.size = instance.size

   bg_color = ListProperty( [ 0, 0, 0, 0 ] )
</code></pre>

<p></p>

<pre><code># application.py
from kivy.app import App
from kivy.clock import Clock
from kivy.graphics import Color
from kivy.lang import Builder
from kivy.uix.floatlayout import FloatLayout
from kivy_mixins import BackgroundColorMixin
from sample_package.tab_test_button import TabTestButton
from sample_package.test_button_layout import TestButtonLayout

Builder.load_file( r"application.kv" )

class RootWidget( FloatLayout, BackgroundColorMixin ):
   def __init__( self, *args, **kwargs ):
      super( RootWidget, self ).__init__( *args, **kwargs )

      Clock.schedule_interval( self._clock_interval_expiration, .75 )

   def _get_random_color_value( self ):
      import random

      r = random.random()
      g = random.random()
      b = random.random()
      a = 1.0

      return [ r, g, b, a ]

   def _clock_interval_expiration( self, dt ):
      color_value = self._get_random_color_value()
      self.bg_color = color_value
      self.ids.estop.color = color_value
      # print( "Color -&gt; {}".format( str( color_value ) ) )

      return True

class TestApp( App ):
   def build( self ):
      result = RootWidget()
      return result
</code></pre>

<p></p>

<pre><code># application.kv
#:kivy 1.8

#:import BoxLayout kivy.uix.boxlayout
#:import Button kivy.uix.button
#:import Label kivy.uix.label
#:import TabbedPanel kivy.uix.tabbedpanel
#:import TabbedPanelItem kivy.uix.tabbedpanel

##:import TabTestButton tab_test_button

&lt;RootWidget&gt;:
   bg_color: 0, 1, 0, 1

   BoxLayout:
      orientation: "vertical"
      size: root.size

      BoxLayout:
         orientation: "horizontal"
         size_hint: ( 1, .25 )

         Label:
            text: "Placeholder text"
            color: 0, 0, 1, 1

         Button:
            id: estop
            text: "The big red button"

      TabbedPanel:
         do_default_tab: False

         TabbedPanelItem:
            text: "One"

            TabTestButton:
               tab_id_string: "one"
               source: "./resources/right-arrow.png"
               bg_color: .25, 0, 0, 1

         TabbedPanelItem:
            text: "Two"

            TabTestButton:
               tab_id_string: "two"
               source: "./resources/right-arrow.png"
               bg_color: 0, .25, 0, 1

         TabbedPanelItem:
            text: "Three"

#            TabTestButton:
#               tab_id_string: "three"
#               source: "./resources/right-arrow.png"
#               bg_color: .0, 0, .25, 1
            TestButtonLayout:
</code></pre>

<p></p>

<pre><code># sample_package/image_button.py
from kivy.uix.behaviors import ButtonBehavior
from kivy.uix.image import Image
from kivy_mixins import BackgroundColorMixin

class ImageButton( ButtonBehavior, Image, BackgroundColorMixin ):
   def __init__( self, *args, **kwargs ):
      super( ImageButton, self ).__init__( **kwargs )
</code></pre>

<p></p>

<pre><code># sample_package/tab_test_button.py
from kivy.properties import StringProperty
from .image_button import ImageButton

class TabTestButton( ImageButton ):
   def __init__( self, *args, **kwargs ):
      super( TabTestButton, self ).__init__( **kwargs )

   tab_id_string = StringProperty( None )

   def on_press( self ):
      print( "Button on tab {} pressed.".format( self.tab_id_string ) )
</code></pre>

<p></p>

<pre><code># sample_package/test_button_layout.py
from kivy.uix.boxlayout import BoxLayout
from tab_test_button import TabTestButton

class TestButtonLayout( BoxLayout ):
   def __init__( self, **kwargs ):
      super( TestButtonLayout, self ).__init__( orientation = "horizontal", **kwargs )
      self._construct( **kwargs )

   def _construct( self, **kwargs ):
      tab_item_color = [ .0, 0, .25, 1 ]

      button_0 = TabTestButton( tab_id_string = "three (1)", source = "./resources/right-arrow.png", **kwargs )
      button_0.bg_color = tab_item_color

      button_1 = TabTestButton( tab_id_string = "three (2)", source = "./resources/right-arrow.png", **kwargs )
      button_1.bg_color = tab_item_color

      self.add_widget( button_0 )
      self.add_widget( button_1 )
</code></pre>