如何从 Kivy 中的另一个小部件访问某些小部件属性?
问题描述
好吧,假设我希望某个小部件中的标签使用另一个小部件内标签中的文本:
Ok let's say I want that label in some widget to use text from label inside another widget:
<SubWidget@RelativeLayout>:
Label:
text: str(root.parent.ids.first.text)
<RootWidget>:
Label:
id: first
center_x: 100
text: "text"
SubWidget:
id: second
center_x: 200
这可行,但似乎不是很好的解决方案.如果我将 first
放在另一个小部件中,我需要在代码中的任何地方更改对它的引用(这可能导致错误).
This works but doesn't seem to be nice solution. If I'll place first
inside another widget I'll need to change reference to that it everywhere in the code (that can lead to errors).
我的第一个想法是至少在根级别存储对 first
的引用并对其进行引用:
My first idea was at least to store reference to first
at root level and reference to it:
<SubWidget@RelativeLayout>:
Label:
text: str(root.parent.l.text)
<RootWidget>:
l: first
Label:
id: first
center_x: 100
text: "text"
SubWidget:
id: second
center_x: 200
但这会导致异常:
AttributeError: 'NoneType' object has no attribute 'text'
这很令人困惑,因为如果我写类似 text: str(root.parent.l)
我会看到 Label object
而不是 NoneType
.
This is confusing since if I'll write something like text: str(root.parent.l)
I'll see Label object
rather than NoneType
.
所以我有两个问题:
- 为什么第二种解决方案不起作用?如何解决?
- 一般来说,从另一个小部件访问某些小部件属性的最佳方式是什么?我可以让它独立于小部件层次结构吗?
解决方案
对象属性
l
可能会在第一次事件循环迭代之后 被填充,而您正试图在第一次迭代中访问它.您可以将其延迟到第二次迭代以使其正常工作.
The object property
l
probably gets populated after the first event loop iteration, while you are trying to access it within the first. You could delay it till the second iteration to make it work.
最强大的方法是从 python 代码中绑定这些属性,但是有一些 kv lang 技巧可以使其更简单.这是我最喜欢的方法:
The most powerful approach is to bind those properties from inside python code, but there are some kv lang tricks to make it simpler. This is my favorite method:
BoxLayout
Label
id: label
text: 'hello world'
SubWidget
label_text: label.text
<SubWidget@BoxLayout>
label_text: 'none'
Label
text: root.label_text
相关文章