【问题标题】:Python (Kivy) - How to dynamically add buttons and bind with different argumentsPython (Kivy) - 如何动态添加按钮和绑定不同的参数
【发布时间】:2023-04-03 16:09:01
【问题描述】:

我已经知道如何在 kivy 中动态添加按钮,以及如何将它们绑定到带有额外参数的方法。

我将尝试通过汽车示例尽可能好地描述我的问题:
我有点使用MVC。用户应该能够看到汽车列表,并且他还能够编辑、添加和删除(基本的 CRUD)。
Car Model 具有 id、car_name 和 description 等属性

控制器执行 CRUD 操作。
写入时会将数据存储在 .json 文件中,读取时会将所有数据存储在变量中。
我对控制器或模型没有任何问题,这很好。

现在我想显示用户在我的视图 (Kivy) 中创建的所有汽车。我决定所有汽车都将在主窗口中显示为带有汽车名称的按钮。当我点击按钮时,它应该会显示一个包含汽车信息的新屏幕。但我不知道如何从单击的按钮传递汽车的 ID...
到目前为止,这就是我的代码(不工作):

class MainWindow(GridLayout):
    def __init__(self, **kwargs):
        super(MainWindow, self).__init__(**kwargs)
        self.cols = 1
        for car in car_cache.car_list:
            btn_car = Button(text=car.car_name, font_size=40)
            btn_car.bind(on_press=lambda x: self.select_car(btn_car, car.id))
            self.add_widget(btn_car)

    def select_car(self, instance, id):
        print(f'Car {id} selected')

按钮显示正确。问题是,无论我点击什么按钮,它总是打印添加到小部件的汽车的最后一个 ID。

感谢您的帮助。

【问题讨论】:

  • lambda 就是这样工作的。尝试改用partial
  • 你可以使用partial,但是如果你想使用lambda,你需要绑定目标对象。 lambda x, bound_car=car: self.select_car(btn_car, bound_car)
  • 谢谢。 @JohnAnderson 你的方法奏效了。
  • @Anthony 你的方法也奏效了。谢谢。注意:对于这两种方法,btn_car 都需要是 MainWindow 的一个属性...所以 'self.btn_car'

标签:
python
kivy