Acceso al valor de la propiedad del widget hijo en kivy lang y python

  1. ¿Cómo puedo sobrescribir el valor predeterminado de un elemento secundario de Kivy? es decir, MyWidget.label es “predeterminado” pero quiero cambiarlo a, por ejemplo, “tortuga púrpura” cuando un hijo de MyRootWidget ?

  2. Puedo acceder a los niños de los niños como lo he hecho en MyRootWidget.__init__() , pero me parece incómodo, especialmente para un árbol profundo … ¿hay una forma más elegante de hacerlo?

He estado revisando las páginas de Kivy lang y Widget, pero no he podido entender una solución si está allí. No he visto bastante este problema en las páginas SO (aunque sí respondieron una pregunta diferente mientras estaba buscando).

 from kivy.app import App from kivy.lang import Builder from kivy.uix.boxlayout import BoxLayout from kivy.properties import ObjectProperty, StringProperty root = Builder.load_string(''' : orientation: 'vertical' Label: id: label text: 'DEFAULT' : id: root_widget MyWidget: id: w1 # (---1---) ''') class MyRootWidget(BoxLayout): w1 = ObjectProperty() def __init__(self, **kwargs): super().__init__(**kwargs) print(self.ids.w1.ids.label.text) # (---2---) class MainApp(App): def build(self): return MyRootWidget() if __name__ == '__main__': MainApp().run() 

En primer lugar, antes de implementar cualquier código, debe diseñar sus clases.

Primero lo haremos con MyWidget, en sus requisitos, usted indica que desea que el texto sea modificable por lo que debe ser una propiedad raíz.

 MyWidget ┌--------------------------┐ | | | ┌-------------┐ text---┼---> | | Label | | | | | *text ---┼-----┘ | | └-------------┘ | └--------------------------┘ 

Lo mismo se podría hacer con MyRootWidget:

 MyRootWidget ┌-----------------------------┐ | | | ┌-------------┐ obj_widget--┼---> | | MyWidget --┼-----┘ | | | | | | └-------------┘ | └-----------------------------┘ 

La profundidad de la propiedad depende de sus requisitos, pero si observamos la exposición de una propiedad, esto implica crear una propiedad en la raíz y hacer un enlace para que cuando se modifique la propiedad raíz también se modifique la propiedad interna.

Implementando lo anterior se obtiene lo siguiente:

 from kivy.app import App from kivy.lang import Builder from kivy.uix.boxlayout import BoxLayout from kivy.properties import ObjectProperty, StringProperty root = Builder.load_string(''' : text: "DEFAULT" obj_label: label orientation: 'vertical' Label: id: label text: root.text : obj_widget: w1 MyWidget: id: w1 text: "purple turtle" ''') class MyRootWidget(BoxLayout): def __init__(self, **kwargs): super().__init__(**kwargs) print(self.obj_widget.text) class MainApp(App): def build(self): return MyRootWidget() if __name__ == '__main__': MainApp().run() 

Así que para evitar los identificadores, puedes crear un alias para el widget de niños como lo hice con obj_widget, que es un alias de w1.

Por diseño, no debe acceder al árbol completo directamente, pero debe modificar la propiedad de una capa y esta capa si se modifica, luego debe actualizar los datos necesarios en su parte interna para evitar el acoplamiento entre clases.