Home > Software design >  Kivy Buttons on_press method doesn't work
Kivy Buttons on_press method doesn't work

Time:07-04

So I have written this basic kivy code. I want to read sentences from a file, and dynamically create buttons for each one of them. Then, I want these buttons to disappear when they are clicked. In a for loop, I create my buttons, and put my buttons with the index i in a list. Then with the on_press method, it should delete itself.

Button_List[i].bind(on_press= lambda x: self.remove_widget(Button_List[i]))

So there is a Button in Button_List[i] , and when it is clicked, it should run:

self.remove_widget(Button_List[i])

so it should delete itself

I have 5 buttons for example, the problem is, that it whichever button I click, it deletes the button with the highest index. And the other buttons dont get deleted. I feel like kivy is only executing the last index, but I am not sure.

Here is my code:

new.py:

import kivy.uix.button as kb
from kivy.app import App
from kivy.uix.widget import Widget
from Nils_Programm_verkürzt import lektionstextlesen
from kivy.uix.gridlayout import GridLayout

sentences = ['example_sentence1','example_sentence2','example_sentence3','example_sentence4','example_sentence5',]

class Button_Widget(Widget):
    def __init__(self, **kwargs):
        super(Button_Widget, self).__init__(**kwargs)
        global Button_List
        Button_List = []
        for i in range(len(sentences)):
         print(i)
         Button_List.append(kb.Button(text=sentences[i],pos=(self.width * i, self.height * i)))
         Button_List[i].size = 50, 50
         print('binding'  str(i))
         Button_List[i].bind(on_press= lambda x: self.remove_widget(Button_List[i]))
         print(Button_List[i])
         self.add_widget(Button_List[i])




class ButtonApp(App):

    def build(self):
        return Button_Widget()


if __name__ == "__main__":
    ButtonApp().run()

Your help is very much appreciated :).

CodePudding user response:

That's a common problem when using lambda in a loop. They all get the last value of the loop. A fix is to create a new variable that holds the current loop variable value. So, try replacing:

     Button_List[i].bind(on_press= lambda x: self.remove_widget(Button_List[i]))

with:

        Button_List[i].bind(on_press= lambda x, j=i: self.remove_widget(Button_List[j]))
  • Related