Доступ к значению свойства дочернего виджета в kivy lang и python - PullRequest
0 голосов
/ 26 ноября 2018
  1. Как перезаписать значение по умолчанию для дочернего элемента виджета Kivy?то есть MyWidget.label по умолчанию, но я хочу изменить его, например, на «фиолетовую черепаху», когда ребенок MyRootWidget?

  2. Я могу получить доступ к детям детей, как и ямы сделали в MyRootWidget.__init__(), но это кажется громоздким, особенно для глубокого дерева ... есть ли более элегантный способ сделать это?

Я просматривал Кивистраницы lang и Widget, но не смогли понять решение, если оно есть.Я не видел этой проблемы на SO страницах (хотя они отвечали на другой вопрос, пока я искал).

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('''
<MyWidget@BoxLayout>:
    orientation: 'vertical'
    Label:
        id: label
        text: 'DEFAULT'

<MyRootWidget@BoxLayout>:
    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()

1 Ответ

0 голосов
/ 26 ноября 2018

Прежде всего, прежде чем реализовывать какой-либо код, вы должны спроектировать свои классы.

Сначала мы сделаем это с MyWidget, в ваших требованиях вы указываете, что вы хотите, чтобы текст был изменяемым, поэтому он должен бытькорневое свойство.

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

То же самое можно сделать с MyRootWidget:

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

Глубина свойства зависит от ваших требований, но если мы наблюдаем выставление свойства, это подразумевает созданиесвойство в корне и создание привязки таким образом, чтобы при изменении корневого свойства также изменялось внутреннее свойство.

Реализуя вышесказанное, вы получаете следующее:

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('''
<MyWidget@BoxLayout>:
    text: "DEFAULT"
    obj_label: label
    orientation: 'vertical'
    Label:
        id: label
        text: root.text

<MyRootWidget@BoxLayout>:
    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()

Таким образом, чтобы избежатьидентификаторы, которые вы можете создать псевдоним для дочернего виджета, как я сделал с obj_widget, который является псевдонимом w1.

По своей конструкции вы не должны получать прямой доступ ко всему дереву, но вы должны изменить свойство слоя, и этослой, если он изменен, то вы должны обновить необходимые данные во внутренней части, чтобы избежать связи между классомs.

...