我正在尝试使用for循环向网格布局滚动视图添加一组按钮。但是,即使在按下按钮之前,所有按钮都会触发按下事件。我该如何解决这个问题?
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.uix.scrollview import ScrollView
from kivy.core.window import Window
from kivy.app import runTouchApp
import webbrowser
def btnsclicked(id, url):
print 'btn id '+id+' clicked'
webbrowser.open(url)
layout = GridLayout(cols=1, spacing=10, size_hint_y=None)
layout.bind(minimum_height=layout.setter('height'))
for i in range(5):
url= 'https://www.google.com'
btn = Button(text=str(i), size_hint_y=None, height=40, id='b'+str(i))
btn.bind(on_press =btnsclicked('b'+str(i), url))
layout.add_widget(btn)
root = ScrollView(size_hint=(1, None), size=(Window.width, Window.height))
root.add_widget(layout)
runTouchApp(root)
答案 0 :(得分:2)
对于on_press
,您调用函数而不是指定要使用的函数。尝试:
btn.bind(on_press=lambda x: btnsclicked('b' + str(i), url))
如果您想处理参数,请参阅Event dispatcher:
def btnsclicked(*args):
id_, url = args
print('btn id {} clicked'.format(id_))
webbrowser.open(url)
btn.bind(on_press=btnsclicked)
答案 1 :(得分:1)
因为你在传递args时实际上正在调用你的回调:
btn.bind(on_press =btnsclicked('b'+str(i), url))
Doc示例说:
def callback(instance):
print('The button <%s> is being pressed' % instance.text)
btn1 = Button(text='Hello world 1')
btn1.bind(on_press=callback)
你必须传递一个只接受1个参数的函数(不是函数调用):激活的小部件的实例。
使用定义函数的lambda
表达式来执行此操作:
btn.bind(on_press = lambda x : btnsclicked('b'+str(i), url))
触发事件时,将使用一个参数调用on_press
回调:小部件ID。这会调用lambda
函数调用btnsclicked
来放弃此参数(此处不需要),但会传递您的文本ID和要关联的网址。