单击按钮时添加和删除 Kivy 语言中的代码元素

Appending and removing code elements within Kivy language on button click

我编写了一个由各种按钮和嵌套布局组成的 Kivy GUI。我希望能够通过单击按钮在这些布局之一(特别是滚动布局)中附加一段代码 n 次。由于我对 Kivy 还很陌生,而且我似乎找不到关于这方面的教程,所以我在这里展示它。

这里是 Python 代码:

import kivy
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.widget import Widget


class Interface(Widget):
    pass

class GUI(App):
    def build(self):
        return Interface()

if __name__ == "__main__":
    GUI().run()


Kivy 总代码:

<Interface>:
    GridLayout:
        padding:0
        size: root.width, root.height
        cols:1
        #Top buttons
        GridLayout:
            size_hint: 1, 0.07
            padding:0
            cols:1
            Button:
                text:"Add Phase"
        #Chart areas
        ScrollView:
            do_scroll_y:False
            BoxLayout:
                orientation: "vertical"
                size_hint_x: None
                width: self.minimum_width
                GridLayout:
                    size_hint_x: None
                    width: self.minimum_width
                    cols:20



                    #Phase template
                    GridLayout:
                        width: 200
                        size_hint_x: None
                        cols:1
                        TextInput:
                            size_hint: 1, 0.06
                            halign: 'center'
                            hint_text:"Phase"
                        TextInput:
                            size_hint: 1, 0.06
                            halign: 'center'
                            hint_text:"Step"
                        Button:
                            size_hint:1, 0.07
                            text:"Add Step"
                        GridLayout:
                            cols:20

                            #Step template
                            GridLayout:
                                width: 100
                                size_hint_x: None
                                cols:1
                                TextInput:
                                    size_hint: 1, 0.06
                                    halign: 'center'
                                    hint_text:"Var1"
                                TextInput:
                                    size_hint: 1, 0.06
                                    halign: 'center'
                                    hint_text:"Var2"
                                Button:
                                    background_normal: ''
                                    background_color: 0.28,0.59,0.72,1
                                    text:"Test"
                                Button:
                                    size_hint:1, 0.07
                                    text:"Delete"


                        Button:
                            background_color: 0.8,0,0,1
                            size_hint:1, 0.07
                            text:"Delete"


您将在 Kivy 代码中看到这些是名为 #Phase template 的注释部分。基本上按下按钮 Add Phase,整个部分及其子元素应附加到直接父元素 GridLayout

在这里您可以按“添加阶段”按钮:

这将导致:

最后,按下 Delete 按钮应该会删除特定的附加代码部分。

同样,不知道如何从 Kivy 语言处理这个问题,使用它似乎有点死板。但我相信我想做的事一定能完成。

实现此目的的一种方法是创建 Phase class,并添加 kv 规则以构建 Phase 的实例。然后,在 kv 中,您可以使用 Factory.Phase() 创建新实例。

将您的 kv 修改为:

#:import Factory kivy.factory.Factory
<Interface>:
    GridLayout:
        padding:0
        size: root.width, root.height
        cols:1
        #Top buttons
        GridLayout:
            size_hint: 1, 0.07
            padding:0
            cols:1
            Button:
                text:"Add Phase"
                on_release: grid.add_widget(Factory.Phase())  # this adds another Phase
        #Chart areas
        ScrollView:
            do_scroll_y:False
            BoxLayout:
                orientation: "vertical"
                size_hint_x: None
                width: self.minimum_width
                GridLayout:
                    id: grid  # added id to identify where to add new Phase instances
                    size_hint_x: None
                    width: self.minimum_width
                    cols:20

                    # initial Phase instance
                    Phase:

#Phase template
<Phase@GridLayout>:
    width: 200
    size_hint_x: None
    cols:1
    TextInput:
        size_hint: 1, 0.06
        halign: 'center'
        hint_text:"Phase"
    TextInput:
        size_hint: 1, 0.06
        halign: 'center'
        hint_text:"Step"
    Button:
        size_hint:1, 0.07
        text:"Add Step"
    GridLayout:
        cols:20

        #Step template
        GridLayout:
            width: 100
            size_hint_x: None
            cols:1
            TextInput:
                size_hint: 1, 0.06
                halign: 'center'
                hint_text:"Var1"
            TextInput:
                size_hint: 1, 0.06
                halign: 'center'
                hint_text:"Var2"
            Button:
                background_normal: ''
                background_color: 0.28,0.59,0.72,1
                text:"Test"
            Button:
                size_hint:1, 0.07
                text:"Delete"


    Button:
        background_color: 0.8,0,0,1
        size_hint:1, 0.07
        text:"Delete"
        on_release: root.parent.remove_widget(root)  # delete this Phase

关键点是 <Phase@GridLayout> 规则、新的 grid id 以及 Add Phase 按钮中 Factory 的使用。