我遇到了一个问题,即应用程序在其他任何事情发生之前立即运行按钮的on-unu-press命令。如果我用一个.kv的布局,它工作得很好,但我想能够管理按钮使用一个简单的列表。在
class AppBase(Widget):
def Launcher(self, launchapp):
os.system(launchapp)
def BuildLayout(self):
layout = GridLayout( rows=4, row_force_default = True, row_default_height = 100, col_force_default = True, col_default_width = 300 )
with open('config.txt', 'rb') as f:
reader = csv.reader(f, delimiter="|")
for row in reader:
launchbutton = Button( text = row[0], background_normal = 'tile.png', on_press = self.Launcher(row[1]) )
layout.add_widget(launchbutton)
return layout
class MyApp(App):
def build(self):
Config.set('graphics', 'width', 1920)
Config.set('graphics', 'height', 400)
return AppBase().BuildLayout()
if __name__ == '__main__':
MyApp().run()
您没有将回调传递到
^{1}$Button
,而是在此时实际执行该函数。更改此项:为此:
^{pr2}$现在传递一个未命名的函数,该函数将在
on_press
事件时调用self.Launcher
,而不是在创建Button
时将其设置为self.Launcher
的返回结果。在更新:由于某些原因,}事件实际上并没有分配给
on_press
和{Button.__init__
中的回调,事件本身只是注册而没有结果。(这在我看来是一个bug,但我对Kivy还不太熟悉,不能肯定地说。)您需要显式地bind
回调才能正常工作:注意,回调实际上接收一个参数,我在lambda中以
widget
的形式包含了该参数。在更新2:我应该早点发现这个,抱歉,但是我已经将我的本地测试用例减少到一个按钮。在循环中执行此操作时:
每次调用}的值。lambda已经创建了一个闭包,它包含来自周围范围的
funcs[n]()
,其中n in [0..9]
都将返回9
,而不是预期的{x
。但是,x
的值在循环过程中会发生变化,到最后它是9
。现在,funcs
中的所有lambda都持有对9
的引用。可以通过向lambda的局部作用域添加所需的值来避免这种情况:这会将lambda局部变量
x
指向外部作用域中循环变量x
所引用的同一对象。如果我们使用不同的变量名,情况会更明显:但是
x=x
形式在这种情况下非常常见。因此,为了确保每个按钮使用正确的值,您应该能够执行以下操作:在这里,您将当前值
row[1]
绑定到lambda局部作用域中的appname
,因此当调用它时,它将传递给Launcher
。在相关问题 更多 >
编程相关推荐