绑定函数到Kivy标签时,向函数传递了错误的参数。

huangapple go评论94阅读模式
英文:

Binding a function to labels in kivy is passing the wrong parameters to the function

问题

以下是您提供的代码的翻译:

  1. 我有一堆标签是使用for循环创建的每个标签都绑定了一个函数该函数传递不同的参数但是当我单击任何标签时它调用该函数并使用最后一个标签的参数无论单击哪个标签
  2. 这是我的代码
  3. from kivy.uix.screenmanager import ScreenManager, Screen, NoTransition
  4. from kivy.properties import ObjectProperty, StringProperty
  5. from kivy.core.window import Window
  6. from kivy.uix.label import Label
  7. from kivy.app import App
  8. def findVideos(name): # 返回一个二维数组
  9. class findWindow(Screen):
  10. songName = ObjectProperty()
  11. videoInfo = []
  12. def submitBtn(self):
  13. findWindow.videoInfo = findVideos(self.songName.text)
  14. for video in findWindow.videoInfo:
  15. label = Label(text='[ref=world]world[/ref]', size_hint_y=None, height=12, text_size=(250, 20), markup=True)
  16. label.bind(on_ref_press=lambda x, y: findWindow.changeScreen(self, 'download', label)) # 我相信这是问题所在
  17. findWindow.videoInfo[findWindow.videoInfo.index(video)].append(label)
  18. self.ids.gridLay.add_widget(label)
  19. def changeScreen(self, screen, label):
  20. self.parent.current = screen
  21. for video in findWindow.videoInfo:
  22. if video[2] == label: self.parent.current_screen.ids.downloadWindowId.text = video[0] # 总是与数组中的最后一个项目匹配
  23. class MyApp(App):
  24. def build(self):
  25. sm = ScreenManager(transition=NoTransition())
  26. sm.add_widget(findWindow(name='find'))
  27. return sm
  28. MyApp().run()

以下是您提供的Kivy部分的翻译:

  1. <findWindow>:
  2. songName: songName
  3. FloatLayout:
  4. TextInput:
  5. id: songName
  6. hint_text: "搜索"
  7. multiline: False
  8. font_size: 14
  9. size_hint: (0.6, 0.05)
  10. pos_hint: {"x":0.075, "y":0.925}
  11. Button:
  12. text: "提交"
  13. on_release: root.submitBtn()
  14. font_size: 14
  15. size_hint: (0.2, 0.05)
  16. pos_hint: {"x":0.675, "y":0.925}
  17. ScrollView:
  18. do_scroll_x: False
  19. do_scroll_y: True
  20. size_hint: (0.90, 0.7)
  21. pos_hint: {"x":0.05, "y":0.11}
  22. GridLayout:
  23. id: gridLay
  24. cols: 1
  25. size_hint_y: None
  26. spacing: 14
  27. height: self.minimum_height

请注意,由于代码中的HTML实体(如&amp;&quot;)未进行翻译,您需要根据需要进行修复。希望这有助于您理解代码并解决问题。如果您有进一步的问题,请随时提出。

英文:

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:

  1. from kivy.uix.screenmanager import ScreenManager, Screen, NoTransition
  2. from kivy.properties import ObjectProperty, StringProperty
  3. from kivy.core.window import Window
  4. from kivy.uix.label import Label
  5. from kivy.app import App
  6. def findVideos(name): #returns a 2d array
  7. class findWindow(Screen):
  8. songName = ObjectProperty()
  9. videoInfo = []
  10. def submitBtn(self):
  11. findWindow.videoInfo = findVideos(self.songName.text)
  12. for video in findWindow.videoInfo:
  13. label = Label(text=&#39;[ref=world]world[/ref]&#39;, size_hint_y=None, height=12, text_size=(250, 20), markup=True)
  14. label.bind(on_ref_press=lambda x, y: findWindow.changeScreen(self, &#39;download&#39;, label)) #i believe this is the problem
  15. findWindow.videoInfo[findWindow.videoInfo.index(video)].append(label)
  16. self.ids.gridLay.add_widget(label)
  17. def changeScreen(self, screen, label):
  18. self.parent.current = screen
  19. for video in findWindow.videoInfo:
  20. if video[2] == label: self.parent.current_screen.ids.downloadWindowId.text = video[0] #always matches with the last item in the array
  21. class MyApp(App):
  22. def build(self):
  23. sm = ScreenManager(transition=NoTransition())
  24. sm.add_widget(findWindow(name=&#39;find&#39;))
  25. return sm
  26. MyApp().run()

Here is my kivy:

  1. &lt;findWindow&gt;:
  2. songName: songName
  3. FloatLayout:
  4. TextInput:
  5. id: songName
  6. hint_text: &quot;Search&quot;
  7. multiline: False
  8. font_size: 14
  9. size_hint: (0.6, 0.05)
  10. pos_hint: {&quot;x&quot;:0.075, &quot;y&quot;:0.925}
  11. Button:
  12. text: &quot;Submit&quot;
  13. on_release: root.submitBtn()
  14. font_size: 14
  15. size_hint: (0.2, 0.05)
  16. pos_hint: {&quot;x&quot;:0.675, &quot;y&quot;:0.925}
  17. ScrollView:
  18. do_scroll_x: False
  19. do_scroll_y: True
  20. size_hint: (0.90, 0.7)
  21. pos_hint: {&quot;x&quot;:0.05, &quot;y&quot;:0.11}
  22. GridLayout:
  23. id: gridLay
  24. cols: 1
  25. size_hint_y: None
  26. spacing: 14
  27. 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, &#39;download&#39;, video[0])) aswell, however it still used the video[0] from the last label.

答案1

得分: 0

The lambda函数直到引用被按下才被评估,因此label参数将始终是label的最后一个值。修复方法是创建一个临时参数,该参数获取当前的label值,并在lambda中使用它。就像这样:

  1. label.bind(on_ref_press=lambda x, y, lab=label: findWindow.changeScreen(self, 'download', lab)) # 我相信这是问题所在
  2. 临时参数`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:

  1. label.bind(on_ref_press=lambda x, y, lab=label: findWindow.changeScreen(self, &#39;download&#39;,
  2. lab)) # i believe this is the problem

The temporary parameter lab gets the current value of label.

huangapple
  • 本文由 发表于 2023年5月18日 06:37:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/76276617.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定