kurdish devil
kurdish devil

Reputation: 131

KivyMD: can't bind function

i'm generating multiple buttons,i want to bind each button on_release event and each button return a unique ID to the assigned function, here's my whole code:-

class APP(MDApp):
    class MovieScreen(Screen):
        def on_enter(self, *args):
            pass

    def addMoreMovies(self, imdbid):
        print(imdbid)

    Config.set('graphics', 'width', '450')
    Config.set('graphics', 'height', '700')
    Config.write()

    def build(self):
        self.theme_cls = ThemeManager()
        self.theme_cls.primary_palette = "Green"
        self.theme_cls.theme_style = "Dark"
        screen = Builder.load_string(screen_helper)
        return screen

    def on_start(self):
        amountOfMovies = 10

        movies = getMovie(amountOfMovies)
        for i in range(len(movies[0])):
            image = movies[1][i]
            name = movies[0][i]
            imdbid = movies[2][i]
            tile=SmartTileWithLabel()
            tile.id=str(imdbid)
            tile.bind(on_release=lambda x: APP.addMoreMovies(self,imdbid=imdbid))
            tile.source=str(image)
            tile.text=str(name)
            tile.size=(182,268)
            tile.height='240dp'
            tile.size_hint_y=None
        self.root.ids.grid.add_widget(tile)

the code kinda works, but all the buttons are returning the last assigned ID,

i realized that i have to change my code from

tile.bind(on_release=lambda x: APP.addMoreMovies(self,imdbid=imdbid))

to

tile.bind(on_release=APP.addMoreMovies(self,imdbid=imdbid))

so that each button instance it's own function. but when i run the code i get this following error:-


File "kivy\_event.pyx", line 419, in kivy._event.EventDispatcher.bind
 AssertionError: None is not callable

Upvotes: 0

Views: 487

Answers (1)

furas
furas

Reputation: 143187

on_release= needs function's name without () (and without arguments) so when you press button then it uses () to execute it.

If you use

on_release=APP.addMoreMovies() 

then you execute function at start and it works like

result = APP.addMoreMovies() 
bind(on_release=result)

but APP.addMoreMovies() returns None so you have

result = None  # APP.addMoreMovies() 
bind(on_release=result)

and this gives

bind(on_release=None)

so you error None is not callable


You should keep version with lambda but you may have to send imdb in different way

bind(on_release=lambda x, value=imdbid: APP.addMoreMovies(self,imdbid=value))

and then every button should use own value

Upvotes: 1

Related Questions