【问题标题】:Clearing all widgets of a root widget清除根小部件的所有小部件
【发布时间】:2021-05-15 18:47:39
【问题描述】:

我在使用 python 3.7 的 kivy 中遇到了我的代码问题:

我的 .py 代码的一部分:

class PokemonWindow(Screen):
    def __init__(self, **kwargs):
        super(PokemonWindow, self).__init__(**kwargs)
        self.form_button = ObjectProperty(None)
        self.type_grid = ObjectProperty(None)
    
    def create_form_buttons(self, count, form_list):
        e = 0
        for i in range(count):
            self.form_button = Button(text=form_list[e])
            self.type_grid.add_widget(self.form_button)
            e += 1

    def delete_form_buttons(self):
        self.type_grid.clear_widgets()

.kv 代码的一部分:

<PokemonWindow>:
    name: "pokemonWindow"
    search_field: search_field
    search_button: search_button
    type_grid: type_grid

    MDGridLayout:
        cols: 1
        MDToolbar:
            title: "Main toolbar"

    MDFloatLayout:
        MDTextField:
            id: search_field
            mode: "rectangle"
            hint_text: "Pokemon name"
            size_hint_x: .6
            size_hint_y: .05
            pos_hint: {"center_x": .38, "y": 0.875}

        MDRaisedButton:
            id: search_button
            size_hint_x: .2
            size_hint_y: .025
            pos_hint: {"center_x": .85, "y": 0.884}
            text: "Search"
            on_press: root.create_buttons(root.get_searched_pokemon_forms(search_field.text)[0], root.get_searched_pokemon_forms(search_field.text)[1])

    MDGridLayout:
        id: type_grid
        rows: 2
        cols: 4
        size_hint_x: .8
        size_hint_y: .05
        pos_hint: {"x": .1, "y": .8}

基本上,我调用 create_form_buttons() 方法,该方法在将字符串输入文本输入字段 (search_field) 然后单击按钮 (search_button) 后创建几个按钮。

当我再次调用 create_form_buttons() 方法时,我希望删除最后创建的按钮并显示新按钮,所以我想我会创建一个方法 (delete_form_buttons()),它会删除 MDGridLayout 的所有小部件(type_grid) 并像这样实现它:

def create_form_buttons(self, count, form_list):
        e = 0
        self.delete_form_buttons()
        
        for i in range(count):
            self.form_button = Button(text=form_list[e])
            self.type_grid.add_widget(self.form_button)
            e += 1

当我现在第二次调用该方法时,我得到了这个错误:

kivy.uix.gridlayout.GridLayoutException: Too many children in GridLayout. Increase rows/cols!

我确实理解错误 - 它基本上告诉我新按钮不适合我的 type_grid 小部件,这意味着我认为旧按钮没有被正确删除。

所以,我尝试将 delete_form_buttons() 方法放在新按钮的 on_press 事件上,如下所示:

MDRaisedButton:
        text: "Del btns"
        md_bg_color: 1, 0, 1, 1
        size_hint_x: .4
        size_hint_y: .2
        pos_hint: {"x": .525, "y": .275}
        on_press: root.delete_form_buttons()

如果我在 create_form_buttons() 方法中的按钮存在的情况下按下此按钮,它们就会消失。但是当我再次尝试调用 create_form_buttons() 方法时,我得到了与上面提到的相同的错误。我真的不明白为什么。谁能向我解释为什么会发生这种情况以及我该如何解决?

【问题讨论】:

  • 也许您应该将小部件保留在列表中并使用del widget 或者可能有widget.destroy()。或者如果它使用grid.add_widget(),那么它可能需要grid.remove_widget(widget)
  • 如何运行这个函数? count 你有什么价值?也许它太大了?您可以使用print() 来检查变量中的值是否存在问题。它被称为'print debuging'
  • 你可以用for text in form_list: ... Button(text=text)代替for i in range(count):然后你就不需要e = 0,e += 1

标签: python kivy kivymd


【解决方案1】:

属性必须在类的方法之外定义。尝试改变:

class PokemonWindow(Screen):
    def __init__(self, **kwargs):
        super(PokemonWindow, self).__init__(**kwargs)
        self.form_button = ObjectProperty(None)
        self.type_grid = ObjectProperty(None)

到:

class PokemonWindow(Screen):
    form_button = ObjectProperty(None)
    type_grid = ObjectProperty(None)
    def __init__(self, **kwargs):
        super(PokemonWindow, self).__init__(**kwargs)

【讨论】:

  • 感谢您的解释,但它并没有修复错误。
【解决方案2】:

@furas:谢谢,我能够根据你的建议缩短我的代码,并且我意识到我没有清空创建按钮的列表 (self.get_searched_pokemon_forms[0])。

修复此问题后,我的 .py 代码现在如下所示:

    def create_form_buttons(self):
        self.delete_form_buttons()

        for text in self.searched_pokemon_forms:
            btn = Button(text=text)
            self.type_grid.add_widget(btn)

        del self.searched_pokemon_forms[:]

    def delete_form_buttons(self):
        self.type_grid.clear_widgets()

    def form_button_handler(self):
        self.get_searched_pokemon_forms(self.search_field.text)
        self.create_buttons()

以及更改后的 .kv 代码:

    MDRaisedButton:
        id: search_button
        size_hint_x: .2
        size_hint_y: .025
        pos_hint: {"center_x": .85, "y": 0.884}
        text: "Search"
        on_press: root.form_button_handler()

所以现在按钮在创建新按钮之前被删除,在创建新按钮之后,包含名称的列表被清空。

谢谢!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-30
    • 1970-01-01
    • 2015-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多