访问被拒绝 child id
kivy access child id
我想访问 child 的 ID 来决定是否删除小部件。我有以下代码:
main.py
#!/usr/bin/kivy
# -*- coding: utf-8 -*-
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
class Terminator(BoxLayout):
def DelButton(self):
print("Deleting...")
for child in self.children:
print(child)
print(child.text)
if not child.id == 'deleto':
print(child.id)
#self.remove_widget(child)
else:
print('No delete')
class TestApp(App):
def build(self):
pass
if __name__ == '__main__':
TestApp().run()
test.kv
#:kivy 1.9.0
<Terminator>:
id: masta
orientation: 'vertical'
Button:
id: deleto
text: "Delete"
on_release: masta.DelButton()
Button
Button
Terminator
但是当使用 print(child.id)
打印 id 时,它总是 returns: None
。即使 print(child.text)
正确 returns Delete
或
.
问题
- 为什么
child.id
不是 return deleto
,而是 None
?
- 如何检查我没有删除带有“删除”的按钮,而是删除所有其他按钮?
如您在 documentation 中所读:
In a widget tree there is often a need to access/reference other
widgets. The Kv Language provides a way to do this using id’s. Think
of them as class level variables that can only be used in the Kv
language.
从 Python 代码访问 ID 已描述 here。工作示例:
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder
from kivy.properties import ObjectProperty
from kivy.uix.button import Button
Builder.load_string("""
<Terminator>:
id: masta
orientation: 'vertical'
MyButton:
id: deleto
button_id: deleto
text: "Delete"
on_release: masta.DelButton()
MyButton
MyButton
""")
class MyButton(Button):
button_id = ObjectProperty(None)
class Terminator(BoxLayout):
def DelButton(self):
for child in self.children:
print(child.button_id)
class TestApp(App):
def build(self):
return Terminator()
if __name__ == '__main__':
TestApp().run()
要跳过删除带有 "Delete" 标签的按钮,您可以检查其 text
属性。 Hovewer 从循环内部删除会导致错误,因为某些 children 将在您迭代的列表被更改后被跳过:
class Terminator(BoxLayout):
def DelButton(self):
for child in self.children:
self.remove_widget(child) # this will leave one child
您必须创建 children 个列表才能删除:
class Terminator(BoxLayout):
def DelButton(self):
for child in [child for child in self.children]:
self.remove_widget(child) # this will delete all children
你的情况:
class Terminator(BoxLayout):
def DelButton(self):
for child in [child for child in self.children if child.text != "Delete"]:
self.remove_widget(child)
以上是执行任务的不错选择。我在我的代码中非常成功地使用了它们。现在给大家推荐一下Kivy Framework在其文档中直接推荐的可视化代码
看一下,在这个link处清晰可见:
https://kivy.org/doc/stable/api-kivy.uix.widget.html?highlight=objectproperty
你很快就能搞定并使用它。
此部分是 - 小部件 class,锚点是 - ids.
这是用您的 kv 语言定义的 ID 字典。仅当您在 kv 语言代码中使用 id 时才会填充此内容。
ids 是一个 DictProperty,默认为空字典 {}。
为每个根级小部件定义填充 ID。例如:
# in kv
<MyWidget@Widget>:
id: my_widget
Label:
id: label_widget
Widget:
id: inner_widget
Label:
id: inner_label
TextInput:
id: text_input
OtherWidget:
id: other_widget
<OtherWidget@Widget>
id: other_widget
Label:
id: other_label
TextInput:
id: other_textinput
# Then, in python:
>>> widget = MyWidget()
>>> print(widget.ids)
{'other_widget': <weakproxy at 041CFED0 to OtherWidget at 041BEC38>,
'inner_widget': <weakproxy at 04137EA0 to Widget at 04138228>,
'inner_label': <weakproxy at 04143540 to Label at 04138260>,
'label_widget': <weakproxy at 04137B70 to Label at 040F97A0>,
'text_input': <weakproxy at 041BB5D0 to TextInput at 041BEC00>}
>>> print(widget.ids['other_widget'].ids)
{'other_textinput': <weakproxy at 041DBB40 to TextInput at 041BEF48>,
'other_label': <weakproxy at 041DB570 to Label at 041BEEA0>}
>>> print(widget.ids['label_widget'].ids)
{}
我想访问 child 的 ID 来决定是否删除小部件。我有以下代码:
main.py
#!/usr/bin/kivy
# -*- coding: utf-8 -*-
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
class Terminator(BoxLayout):
def DelButton(self):
print("Deleting...")
for child in self.children:
print(child)
print(child.text)
if not child.id == 'deleto':
print(child.id)
#self.remove_widget(child)
else:
print('No delete')
class TestApp(App):
def build(self):
pass
if __name__ == '__main__':
TestApp().run()
test.kv
#:kivy 1.9.0
<Terminator>:
id: masta
orientation: 'vertical'
Button:
id: deleto
text: "Delete"
on_release: masta.DelButton()
Button
Button
Terminator
但是当使用 print(child.id)
打印 id 时,它总是 returns: None
。即使 print(child.text)
正确 returns Delete
或
.
问题
- 为什么
child.id
不是 returndeleto
,而是None
? - 如何检查我没有删除带有“删除”的按钮,而是删除所有其他按钮?
如您在 documentation 中所读:
In a widget tree there is often a need to access/reference other widgets. The Kv Language provides a way to do this using id’s. Think of them as class level variables that can only be used in the Kv language.
从 Python 代码访问 ID 已描述 here。工作示例:
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder
from kivy.properties import ObjectProperty
from kivy.uix.button import Button
Builder.load_string("""
<Terminator>:
id: masta
orientation: 'vertical'
MyButton:
id: deleto
button_id: deleto
text: "Delete"
on_release: masta.DelButton()
MyButton
MyButton
""")
class MyButton(Button):
button_id = ObjectProperty(None)
class Terminator(BoxLayout):
def DelButton(self):
for child in self.children:
print(child.button_id)
class TestApp(App):
def build(self):
return Terminator()
if __name__ == '__main__':
TestApp().run()
要跳过删除带有 "Delete" 标签的按钮,您可以检查其 text
属性。 Hovewer 从循环内部删除会导致错误,因为某些 children 将在您迭代的列表被更改后被跳过:
class Terminator(BoxLayout):
def DelButton(self):
for child in self.children:
self.remove_widget(child) # this will leave one child
您必须创建 children 个列表才能删除:
class Terminator(BoxLayout):
def DelButton(self):
for child in [child for child in self.children]:
self.remove_widget(child) # this will delete all children
你的情况:
class Terminator(BoxLayout):
def DelButton(self):
for child in [child for child in self.children if child.text != "Delete"]:
self.remove_widget(child)
以上是执行任务的不错选择。我在我的代码中非常成功地使用了它们。现在给大家推荐一下Kivy Framework在其文档中直接推荐的可视化代码
看一下,在这个link处清晰可见:
https://kivy.org/doc/stable/api-kivy.uix.widget.html?highlight=objectproperty
你很快就能搞定并使用它。 此部分是 - 小部件 class,锚点是 - ids.
这是用您的 kv 语言定义的 ID 字典。仅当您在 kv 语言代码中使用 id 时才会填充此内容。
ids 是一个 DictProperty,默认为空字典 {}。
为每个根级小部件定义填充 ID。例如:
# in kv
<MyWidget@Widget>:
id: my_widget
Label:
id: label_widget
Widget:
id: inner_widget
Label:
id: inner_label
TextInput:
id: text_input
OtherWidget:
id: other_widget
<OtherWidget@Widget>
id: other_widget
Label:
id: other_label
TextInput:
id: other_textinput
# Then, in python:
>>> widget = MyWidget()
>>> print(widget.ids)
{'other_widget': <weakproxy at 041CFED0 to OtherWidget at 041BEC38>,
'inner_widget': <weakproxy at 04137EA0 to Widget at 04138228>,
'inner_label': <weakproxy at 04143540 to Label at 04138260>,
'label_widget': <weakproxy at 04137B70 to Label at 040F97A0>,
'text_input': <weakproxy at 041BB5D0 to TextInput at 041BEC00>}
>>> print(widget.ids['other_widget'].ids)
{'other_textinput': <weakproxy at 041DBB40 to TextInput at 041BEF48>,
'other_label': <weakproxy at 041DB570 to Label at 041BEEA0>}
>>> print(widget.ids['label_widget'].ids)
{}