I want to access the id of the child to decide whether to delete the widget or not. I have the following code:
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
However when printing the id with: print(child.id), it always returns: None. Even though print(child.text) correct returns Delete or .
child.id not return deleto, but instead None?As you can read in the 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.
Accesing ids from Python code is described here. Working example:
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()
To skip deleting a button with "Delete" label you can examine its text property. Hovewer deleting from inside the loop will lead to the bugs, since some of the children will get skiped after the list you're iterating on will get altered:
class Terminator(BoxLayout):
def DelButton(self):
for child in self.children:
self.remove_widget(child) # this will leave one child
You have to create a list of children to delete:
class Terminator(BoxLayout):
def DelButton(self):
for child in [child for child in self.children]:
self.remove_widget(child) # this will delete all children
In your case:
class Terminator(BoxLayout):
def DelButton(self):
for child in [child for child in self.children if child.text != "Delete"]:
self.remove_widget(child)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With