Как удалить ребенка kivy, который создается динамически?

#python #kivy

Вопрос:

Я создаю пример скрипта kivy, который динамически добавляет кнопку в виджет, а затем автоматически удаляет ее с помощью функции clock.schedule_once. Я смог обратиться к дочерним элементам виджета, чтобы изменить текст кнопки. Однако, когда я пытаюсь удалить сам виджет, он не работает. Вместо этого он дал мне рекурсивную ошибку. Пожалуйста, помогите мне, как удалить виджет. Я добавил несколько комментариев, которые вызывают ошибку в скрипте :

 from kivy.app import App 
from kivy.clock import Clock 
from kivy.uix.boxlayout import BoxLayout 
from kivy.uix.label import Label 
from kivy.uix.button import Button 
from kivy.properties import ObjectProperty

class nbutton(Button):
    buttonid=ObjectProperty(None)

class MyWidget(BoxLayout):
    childs = []
    def __init__(self,*args):
        Clock.schedule_once(self.add_widgets,1)
        Clock.schedule_once(self.remove_widget,2)

        return super().__init__(*args)

    def add_widgets(self,*args):
        #self.r = BoxLayout(size_hint=(1,1),id="nice")
        #self.add_widget(self.r)
        self.add_widget(Button(text="Hello",id='dasd'))
        self.add_widget(Button(text="World",id='q'))
        self.add_widget(Button(text="nice",id='dz'))
        self.add_widget(Button(text="good",id='m'))

    def remove_widget(self,*args):
        #m = App.get_running_app().root.ids.nice
        
        #self.remove_widget(self.children.ids.dasd)
        #self.clear_widgets()
        #for child in [child for child in self.children if child.text != "Hello"]:
            #self.remove_widget(child)
            #print(child)
        #self.remove_widget(self.child.m)
        for chi in self.children:
            self.childs.append(chi)
            print(chi)
        #print(self.childs.text)
        #try:
        self.childs[2].text = 'hihih'


        #------------------------ this part is broken ------------------------------
        self.remove_widget(self.childs[2])
        #------------------------ this part is broken ------------------------------
        # error message:
        #  RecursionError: maximum recursion depth exceeded while calling a Python object






        # except:
        #   pass
        # for c in childs:
        #   self.remove_widget(c)
        #for child in self.children:
            #self.remove(child)
            #print(child.id)
        #   if child.text == 'Hello':
        #       #print(child)
        #       self.remove_widget(child)
        #pass
class MpApp(App):
    def build(self):
        return MyWidget()

if __name__ == '__main__':
    MpApp().run()```
 

Ответ №1:

В рамках вашего remove_widget() метода вы выполняете рекурсию remove_widget() с вызовом:

 self.remove_widget(self.childs[2])
 

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

Кроме того, вы переопределяете remove_widget() метод MyWidget (который является a BoxLayout ), никогда не вызывая фактический remove_widget() метод суперкласса ( BoxLayout ). Таким образом, дочерний виджет на самом деле никогда не удаляется. Возможно, упоминание вашего remove_widget() имени в MyWidget чем-то подобном my_remove_widget() может помочь.

Комментарии:

1. Да, большое тебе спасибо, мой друг, ты спас меня. 😀