I have a bunch of labels that have been created using a for loop, and each one has a function binded to it that passes a different paramater. However, when I click on any of the labels, it calls the function using the parameters of the last label, no matter which one is clicked.
here is my code:
from kivy.uix.screenmanager import ScreenManager, Screen, NoTransition
from kivy.properties import ObjectProperty, StringProperty
from kivy.core.window import Window
from kivy.uix.label import Label
from kivy.app import App
def findVideos(name): #returns a 2d array
class findWindow(Screen):
songName = ObjectProperty()
videoInfo = []
def submitBtn(self):
findWindow.videoInfo = findVideos(self.songName.text)
for video in findWindow.videoInfo:
label = Label(text='[ref=world]world[/ref]', size_hint_y=None, height=12, text_size=(250, 20), markup=True)
label.bind(on_ref_press=lambda x, y: findWindow.changeScreen(self, 'download', label)) #i believe this is the problem
findWindow.videoInfo[findWindow.videoInfo.index(video)].append(label)
self.ids.gridLay.add_widget(label)
def changeScreen(self, screen, label):
self.parent.current = screen
for video in findWindow.videoInfo:
if video[2] == label: self.parent.current_screen.ids.downloadWindowId.text = video[0] #always matches with the last item in the array
class MyApp(App):
def build(self):
sm = ScreenManager(transition=NoTransition())
sm.add_widget(findWindow(name='find'))
return sm
MyApp().run()
Here is my kivy:
<findWindow>:
songName: songName
FloatLayout:
TextInput:
id: songName
hint_text: "Search"
multiline: False
font_size: 14
size_hint: (0.6, 0.05)
pos_hint: {"x":0.075, "y":0.925}
Button:
text: "Submit"
on_release: root.submitBtn()
font_size: 14
size_hint: (0.2, 0.05)
pos_hint: {"x":0.675, "y":0.925}
ScrollView:
do_scroll_x: False
do_scroll_y: True
size_hint: (0.90, 0.7)
pos_hint: {"x":0.05, "y":0.11}
GridLayout:
id: gridLay
cols: 1
size_hint_y: None
spacing: 14
height: self.minimum_height
I don't know what to try at this point. I don't understand why .bind wouldn't bind the correct label in the function? I've tried using findWindow.changeScreen(self, 'download', video[0]))
aswell, however it still used the video[0]
from the last label.
The lambda
function is not evaluated until the reference is pressed, so the label
parameter will always be the last value of the label
. The fix is to create a temporary parameter that takes the current value of label
and uses that in the lambda
. Like this:
label.bind(on_ref_press=lambda x, y, lab=label: findWindow.changeScreen(self, 'download',
lab)) # i believe this is the problem
The temporary parameter lab
gets the current value of label
.