Реализация кода, который вам требуется:
from kivy.config import Config
from kivy.core.window import Window
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.graphics import Rectangle, Color
mainscreen = BoxLayout(orientation='vertical')
label1 = Label(text='label_1', font_size=18, color=(0, 0, 0, 1), size_hint=(None, None))
label1.bind(texture_size=label1.setter('size'))
def update_rect(instance, *args):
rect.pos = instance.pos
rect.size = instance.size
with label1.canvas.before:
Color(1, .5, 0, 1)
rect = Rectangle(pos=label1.pos, size=label1.size)
label1.bind(pos=update_rect, size=update_rect)
label2 = Label(text='label_2', color=(0, 0, 0, 1))
mainscreen.add_widget(label1)
mainscreen.add_widget(label2)
class MyApp(App):
def build(self):
return mainscreen
if __name__ == '__main__':
Config.set('input', 'mouse', 'mouse,multitouch_on_demand')
Window.clearcolor = (1, 1, 1, 1)
MyApp().run()
ИМХО реализация в kv более читабельна и более гибка, когда выполняется связывание, как в случае метки, которая соответствует размеру.
from kivy.config import Config
from kivy.core.window import Window
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.graphics import Rectangle, Color
from kivy.properties import ListProperty
class CustomLabel(Label):
bgcolor = ListProperty([0, 0, 0, 1])
def __init__(self, **kwargs):
if kwargs.get('bgcolor'):
self.bgcolor = kwargs['bgcolor']
kwargs.pop('bgcolor')
super(CustomLabel, self).__init__(**kwargs)
self.bind(texture_size=self.setter('size'))
with self.canvas.before:
self.p = Color(*self.bgcolor)
self.rect = Rectangle(pos=self.pos, size=self.size)
self.on_bgcolor()
self.bind(pos=self.geometry_bind, size=self.geometry_bind)
def on_bgcolor(self, *args):
self.p.rgba = self.bgcolor
def geometry_bind(self, *args):
self.rect.pos = self.pos
self.rect.size = self.size
class MyApp(App):
def build(self):
mainscreen = BoxLayout(orientation='vertical')
label1 = CustomLabel(text='label_1', font_size=18, color=(0, 0, 0, 1), size_hint=(None, None), bgcolor=(1, .5, 0, 1))
label2 = Label(text='label_2', color=(0, 0, 0, 1))
mainscreen.add_widget(label1)
mainscreen.add_widget(label2)
return mainscreen
if __name__ == '__main__':
Config.set('input', 'mouse', 'mouse,multitouch_on_demand')
Window.clearcolor = (1, 1, 1, 1)
MyApp().run()
Пояснение:
bind
: функция bind(foo_property = callback)
отвечает за вызов обратного вызова при изменении foo_property.
setter
: функция setter('foo_property')
генерирует обратный вызов, который позволяет вам установить значение.
Если вы присоединитесь к обеим функциям:
class FooClass(Foo_EventDispatcher):
property_a = FooProperty(initial_value_a)
property_b = FooProperty(initial_value_b)
def __init__(self, **kwargs):
super(FooClass, self).__init__(**kwargs)
self.bind(property_a=self.setter('property_b'))
эквивалентно следующей инструкции в .kv:
<FooClass>:
property_b: self.property_a