我正在使用TabbedPanel开发一个带有自定义小部件的kivy应用程序。自定义小部件能够通过在canvas.before上绘制来指定背景颜色,并在Python代码中指定,而不是kv文件。
当应用程序呈现选项卡时,背景颜色Rectangle将绘制在自定义控件上的小部件顶部。如何在子窗口小部件下创建背景颜色矩形渲染?
Iterable
#: 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 ] )
# 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 -> {}".format( str( color_value ) ) )
return True
class TestApp( App ):
def build( self ):
result = RootWidget()
return result
# 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
<RootWidget>:
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:
# 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 )
# 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 ) )