Kivy - 使用动态 类 设置事件操作

Kivy - Setting event actions using dynamic classes

我目前正在尝试触发一些嵌套在动态 类 中的小部件的事件。更加具体。这是一个示例 kv 文件:

    <UserSelectionInput@BoxLayout>:
        orientation: 'horizontal'
        size_hint: None, 1
        spacing: 4

        lb_text: ''
        lb_id: 'user_selection_label'
        sp_values: '', ''
        sp_id: 'user_selection_spinner'

        Label:
            id: root.lb_id
            size_hint_x: 0.4
            text: root.lb_text
        Spinner:
            id: root.sp_id
            text: 'Select'
            values: root.sp_values

    <InnerBox@AnchorLayout>:
        anchor_x: 'center'
        anchor_y: 'center'

        BoxLayout:
            orientation: 'horizontal'
            size_hint: None, 1
            width: 2 * root.width / 3
            spacing: 1

            UserSelectionInput:
                width: root.width / 3
                sp_values: 'A', 'B', 'C'
                lb_text: 'Type'
                lb_id: 'label_1'
                sp_id: 'spinner_1'
            UserSelectionInput:
                width: root.width / 3
                sp_values: 'D', 'E', 'F', 'G'
                lb_text: 'Version'
                lb_id: 'label_2'
                sp_id: 'spinner_2'

    <MainContent>:
        rows: 3

        Label:
            text: "Some Text"
        GridLayout:
            cols: 1
        InnerBox:

我现在要做的是使用 'InnerBox' 布局中微调器的 'on_text' 事件从关联的 .py 文件中调用一个函数。我不确定这是否是最好的方法,但就可重用性而言,我想对某些小部件组合使用动态 类 的概念。

朱尔茨

不是直接从 BoxLayoutAnchorLayout 继承,而是从它们用 python 代码声明的子类继承,以及您要提供的函数:

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder

Builder.load_string("""
<MyNewWidget@MyBoxLayout>:
    Button:
        text: "test"
        on_press: root.my_function()

<MainWidget>:
    MyNewWidget
""")


class MyBoxLayout(BoxLayout):
    def my_function(self):
        print("MyBoxLayout")


class MainWidget(BoxLayout):
    pass


class MyApp(App):
    def build(self):
        return MainWidget()


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

注意:kv 文件 - 为 id

赋值

id 赋值时,请记住 值不是字符串 。没有引号:

好 -> id: user_selection_labelid: user_selection_spinner

不好 -> id: 'user_selection_label'id: 'user_selection_spinner'

class InnerBox()

中使用on_text

1) kv 文件 - 动态 class 规则,UserSelectionInput

  • 创建与 Spinner
  • text 属性 关联的新 属性

片段

<UserSelectionInput@BoxLayout>:
    text: user_selection_spinner.text

    ...
    Spinner:
        id: user_selection_spinner
        text: 'Select'
        values: root.sp_values

2) kv 文件 - 动态 class 规则,InnerBox

  • 使用on_text属性事件

片段

<InnerBox@AnchorLayout>:
    ...

    BoxLayout:
        ...

        UserSelectionInput:
            on_text:
                print("UserSelectionInput.spinner_1: text=", self.text)

        UserSelectionInput:
            on_text:
                print("UserSelectionInput.spinner_2: text=", self.text)

例子

main.py

from kivy.base import runTouchApp
from kivy.lang import Builder


runTouchApp(Builder.load_string("""
<UserSelectionInput@BoxLayout>:
    orientation: 'horizontal'
    size_hint: None, 1
    spacing: 4

    lb_text: ''
    sp_values: '', ''
    text: user_selection_spinner.text

    Label:
        id: user_selection_label
        size_hint_x: 0.4
        text: root.lb_text
    Spinner:
        id: user_selection_spinner
        text: 'Select'
        values: root.sp_values

<InnerBox@AnchorLayout>:
    anchor_x: 'center'
    anchor_y: 'center'

    BoxLayout:
        orientation: 'horizontal'
        size_hint: None, 1
        width: 2 * root.width / 3
        spacing: 1

        UserSelectionInput:
            width: root.width / 3
            sp_values: 'A', 'B', 'C'
            lb_text: 'Type'
            on_text:
                print("UserSelectionInput.spinner_1: text=", self.text)

        UserSelectionInput:
            width: root.width / 3
            sp_values: 'D', 'E', 'F', 'G'
            lb_text: 'Version'
            on_text:
                print("UserSelectionInput.spinner_2: text=", self.text)

<MainContent@GridLayout>:
    rows: 3

    Label:
        text: "Some Text"
    GridLayout:
        cols: 1
        InnerBox:

MainContent:

"""))