Python3 Kivy按钮点击始终返回最后一个文本问题求助
解决Kivy循环添加按钮点击始终返回最后一个文本的问题
这是Python闭包的延迟绑定导致的问题:lambda表达式里的dish变量不会在循环时立即捕获当前值,而是等到按钮被点击、lambda实际执行时才去读取dish的当前状态——此时循环已经跑完,dish指向列表最后一个元素,所以所有按钮点击都只会打印最后一个文本。
两种可行的解决方法:
方法1:给lambda添加默认参数捕获当前值
修改循环内的按钮创建代码,通过默认参数强制锁定当前循环的dish值:
self.box.add_widget(Button(text=dish, on_press=lambda *args, current_dish=dish: print(current_dish)))
每次循环时,current_dish=dish会把当前的dish值赋值给lambda的默认参数,这样点击按钮时就会使用当时捕获的对应值。
方法2:用functools.partial绑定参数
先导入functools模块,用partial把参数提前绑定到处理函数上:
from functools import partial from kivy.app import App from kivy.uix.boxlayout import BoxLayout from kivy.uix.button import Button dishes=['spaghetti','rice','fish','salad'] class app(App): def build(self): self.box=BoxLayout() def print_dish(dish, *args): print(dish) for dish in dishes: self.box.add_widget(Button(text=dish, on_press=partial(print_dish, dish))) return self.box app().run()
partial(print_dish, dish)会把当前循环的dish值绑定到print_dish的第一个参数,彻底避免闭包延迟绑定的问题。
验证后的完整示例(方法1):
dishes=['spaghetti','rice','fish','salad'] from kivy.app import App from kivy.uix.boxlayout import BoxLayout from kivy.uix.button import Button class app(App): def build(self): self.box=BoxLayout() for dish in dishes: self.box.add_widget(Button(text=dish,on_press=lambda *args, current_dish=dish:print(current_dish))) return self.box app().run()
内容的提问来源于stack exchange,提问作者Tommy
相关产品推荐
相关产品推荐

