在 kivy lang 和 python 中访问 child 小部件 属性 的值
Accessing value of child widget property in kivy lang and python
如何覆盖 Kivy 小部件的默认值 child?即 MyWidget.label
是 'default' 但我想将其更改为例如'purple turtle' 当 MyRootWidget
的 child?
我可以访问children的children,就像我在MyRootWidget.__init__()
中所做的那样,但它看起来很麻烦,尤其是对于一棵深树。 .. 有更优雅的方法吗?
我一直在查看 Kivy 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()
首先,在实施任何代码之前,您必须设计您的 类。
首先,我们将使用 MyWidget 来完成,在您的要求中,您指出您希望文本是可修改的,因此它必须是根 属性。
MyWidget
┌--------------------------┐
| |
| ┌-------------┐ text---┼--->
| | Label | | |
| | *text ---┼-----┘ |
| └-------------┘ |
└--------------------------┘
MyRootWidget 也可以这样做:
MyRootWidget
┌-----------------------------┐
| |
| ┌-------------┐ obj_widget--┼--->
| | MyWidget --┼-----┘ |
| | | |
| └-------------┘ |
└-----------------------------┘
属性 的深度取决于您的要求,但如果我们观察到公开 属性,则意味着在根目录中创建一个 属性 并进行绑定,以便当root 属性 被修改,内部 属性 也被修改。
执行上面的操作你会得到以下结果:
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()
因此,为了避免使用 id,您可以像我对 obj_widget 所做的那样为子部件创建别名,这是 w1 的别名。
根据设计,你不应该直接访问完整的树,但你必须修改一个层的 属性,如果修改了这个层,那么你必须在其内部更新必要的数据,这样我们就避免了类.
之间的耦合
如何覆盖 Kivy 小部件的默认值 child?即
MyWidget.label
是 'default' 但我想将其更改为例如'purple turtle' 当MyRootWidget
的 child?我可以访问children的children,就像我在
MyRootWidget.__init__()
中所做的那样,但它看起来很麻烦,尤其是对于一棵深树。 .. 有更优雅的方法吗?
我一直在查看 Kivy 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()
首先,在实施任何代码之前,您必须设计您的 类。
首先,我们将使用 MyWidget 来完成,在您的要求中,您指出您希望文本是可修改的,因此它必须是根 属性。
MyWidget
┌--------------------------┐
| |
| ┌-------------┐ text---┼--->
| | Label | | |
| | *text ---┼-----┘ |
| └-------------┘ |
└--------------------------┘
MyRootWidget 也可以这样做:
MyRootWidget
┌-----------------------------┐
| |
| ┌-------------┐ obj_widget--┼--->
| | MyWidget --┼-----┘ |
| | | |
| └-------------┘ |
└-----------------------------┘
属性 的深度取决于您的要求,但如果我们观察到公开 属性,则意味着在根目录中创建一个 属性 并进行绑定,以便当root 属性 被修改,内部 属性 也被修改。
执行上面的操作你会得到以下结果:
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()
因此,为了避免使用 id,您可以像我对 obj_widget 所做的那样为子部件创建别名,这是 w1 的别名。
根据设计,你不应该直接访问完整的树,但你必须修改一个层的 属性,如果修改了这个层,那么你必须在其内部更新必要的数据,这样我们就避免了类.
之间的耦合