2016-08-24 38 views
0

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) 

答えて

1

引数を渡すとき、あなたが実際にあなたのコールバックを呼び出しているので:

btn.bind(on_press =btnsclicked('b'+str(i), url)) 

ドク例語る:

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式の操作を行います。ウィジェットID:

btn.bind(on_press = lambda x : btnsclicked('b'+str(i), url)) 

をイベントがトリガされると、on_pressコールバックは一つの引数で呼び出されます。あなたのlambda関数を呼び出してbtnsclickedはこの引数を破棄します(ここでは必要ない)が、テキストIDと関連付けるURLを渡します。

+0

、どのように私は関数を呼び出すことなく、引数を渡すことができます:あなたは、引数に対処したい場合は、Event dispatcherを参照してください

btn.bind(on_press=lambda x: btnsclicked('b' + str(i), url)) 

:試してみてください? – SaikiHanee

+0

は、カスタムコールバックにコールバックを接続するリレー関数であるlamba式を使用しています。 –

+0

ありがとうJean :) – SaikiHanee

2

on_pressの場合は、使用する関数を指定する代わりに関数を呼び出します。ハイジーン

def btnsclicked(*args): 
    id_, url = args 
    print('btn id {} clicked'.format(id_)) 
    webbrowser.open(url) 

btn.bind(on_press=btnsclicked) 
関連する問題