I'm trying to generate a list of buttons in Kivy, binding each on_release event to the action() function of an instance of my Tracks class (stored in track_list). I have made a small example to show the problem. The first 3 buttons print the correct number, but they do not use a for loop... The last 7 buttons do not work, and they always print 9.
bindtest.py
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.widget import Widget
track_list = []
button_list = []
class BindTest(Widget):
global track_list
global button_list
def initialize(self):
for x in range(0, 10):
track_list.append(Tracks(x))
#
# this works, and each button prints its unique 'num' when clicked
#
button_list.append(TrackButton())
button_list[len(button_list) - 1].bind(on_release=lambda y: track_list[0].action())
self.ids.buttons.add_widget(button_list[len(button_list)-1])
button_list.append(TrackButton())
button_list[len(button_list) - 1].bind(on_release=lambda y: track_list[1].action())
self.ids.buttons.add_widget(button_list[len(button_list) - 1])
button_list.append(TrackButton())
button_list[len(button_list) - 1].bind(on_release=lambda y: track_list[2].action())
self.ids.buttons.add_widget(button_list[len(button_list) - 1])
#
# this does not work. each button prints '9' when clicked
#
for x in range(3, 10):
button_list.append(TrackButton())
button_list[len(button_list)-1].bind(on_release=lambda y: track_list[x].action())
self.ids.buttons.add_widget(button_list[len(button_list)-1])
class TrackButton(Button):
pass
class Tracks:
num = ''
def action(self):
print(self.num)
def __init__(self, num):
self.num = num
class BindTestApp(App):
def build(self):
return BindTest()
bindTest = BindTestApp()
bindTest.run()
bindtest.kv
<TrackButton>:
text: 'button'
<BindTest>:
__init__: root.initialize()
BoxLayout:
size: root.size
id: buttons
orientation: 'vertical'