Search code examples
python-3.xkivykivy-language

How to bind buttons to screens that was created in a for loop?


I want to create a set of buttons that controls the current screen that was created within the same for loop.

my .py file

class Profiles(Screen):
    #create button and screens based on items in acc_abr 
    def create_butt(self):
        for i in acc_abr:
            self.ids.sm.add_widget(Screen(name = i))
            self.ids.pro.add_widget(Button(text=i, id=i, on_press = self.switching_function(screename=i)))

    #set current screen
    def switching_function(self, screename):
        self.ids.sm.current = screename

my .kv file

<Profiles>:
    name: "prof"
    on_enter: self.create_butt()
    BoxLayout:
        orientation: "vertical"
        GridLayout:
            rows:1
            id: pro
            size_hint_y: .16
        BoxLayout:
            AccManagement:
                id: sm

Under the create_butt function, I am adding a screen and button (to the appropriate location) for every item in acc_abr.

The problem is, when I try to bind on_press to switching_function. For some reason, when i run the kivy app and call Profile, I get AssertionError: None is not callable

  1. What makes this an valid error?
  2. How can i correctly bind a button to a screen within a for loop?
  3. In a .kv file, a button with an on_press command that changes the current screen within a screen manager(sm) would look something like this: on_press: sm.current = "screen1" So my final question is, how would this be written in a python file? Doesnt work but, Button(on_press=(self.ids.sm.current=i) ???

Solution

  • To use on_press inside of a .py file and pass an argument, you need to either use a lambda function or functools.partial.

    from functools import partial
    ...
    something.add_widget(Button(on_press = partial(self.switching_function, i))
    ...
    

    This is because on_press expects just the name of a function to call (notice there are no parentheses when calling the function in the on_press callback).