英文:
Binding a function to labels in kivy is passing the wrong parameters to the function
问题
以下是您提供的代码的翻译:
我有一堆标签是使用for循环创建的,每个标签都绑定了一个函数,该函数传递不同的参数。但是,当我单击任何标签时,它调用该函数并使用最后一个标签的参数,无论单击哪个标签。
这是我的代码:
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): # 返回一个二维数组
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)) # 我相信这是问题所在
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] # 总是与数组中的最后一个项目匹配
class MyApp(App):
def build(self):
sm = ScreenManager(transition=NoTransition())
sm.add_widget(findWindow(name='find'))
return sm
MyApp().run()
以下是您提供的Kivy部分的翻译:
<findWindow>:
songName: songName
FloatLayout:
TextInput:
id: songName
hint_text: "搜索"
multiline: False
font_size: 14
size_hint: (0.6, 0.05)
pos_hint: {"x":0.075, "y":0.925}
Button:
text: "提交"
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
请注意,由于代码中的HTML实体(如&
和"
)未进行翻译,您需要根据需要进行修复。希望这有助于您理解代码并解决问题。如果您有进一步的问题,请随时提出。
英文:
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.
答案1
得分: 0
The lambda
函数直到引用被按下才被评估,因此label
参数将始终是label
的最后一个值。修复方法是创建一个临时参数,该参数获取当前的label
值,并在lambda
中使用它。就像这样:
label.bind(on_ref_press=lambda x, y, lab=label: findWindow.changeScreen(self, 'download', lab)) # 我相信这是问题所在
临时参数`lab`获取了当前的`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
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论