Kivy / KivyMD:动态生成的带有自己动作的按钮

Kivy / KivyMD: Dynamically generated buttons with own actions

有人可以帮我解决这个问题吗? 我在创建动态按钮并将足够的输出响应绑定到它们时遇到了一些麻烦。

请看下面这个例子⬇:

源代码

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button

class Demo(App):
    buttons = {"1": {"Name": "Button 1", "Action": "Message 1"},
               "2": {"Name": "Button 2", "Action": "Message 2"},
               "3": {"Name": "Button 3", "Action": "Message 3"}}

    def build(self):
        layout = BoxLayout(padding=10, spacing=10)
        for key, value in self.buttons.items():
            layout.add_widget(Button(text=value["Name"], on_press=lambda x: print(value["Action"])))

        return layout

Demo().run()

产出

单击“按钮 1”:
Message 3
单击“按钮 2”:
Message 3
单击“按钮 3”:
Message 3

问题

如您所见,我为每个按钮('Name' 和一些 'Action')创建了一个带有“小节”的字典。 我会说这是一个很好的简单想法。

麻烦的是,即使按钮的名称被很好地识别,每个按钮的输出都是相同的...

有谁知道如何正确地做到这一点并将正确的操作绑定到按钮?

非常感谢。

您可以只替换行:

layout.add_widget(Button(text=value["Name"], on_press=lambda x: print(value["Action"])))

使用以下内容(使用 partial)。

layout.add_widget(Button(text=value["Name"], on_press=partial(print, value["Action"])))

要了解实际情况(以及高级用法),您可以尝试以下操作,

    def build(self):
        ...
        for key, value in self.buttons.items():
            # Create an instance.
            btn = Button(text=value["Name"])
            # Bind to some callback and pass
            # whatever you want using partial.
            btn.bind(on_press=partial(self.callback_method, value["Action"]))
            # Now add it.
            layout.add_widget(btn)
        return layout

    def callback_method(self, val, btn):
        # Note the order of the args that have been passed.
        print(val)