Search code examples
buttonwidgetkivybind

Kivy regarding binding multiple buttons to each individual function


Hi I am new to Kivy and just started programming. I have problem, I want to bind all the buttons i created in the for loops to the on_release for every single buttons. So that to make all buttons once click is able to go different screens. Below is my a small part of my code( I EDITED with more information)

    #this are the pictures of the buttons
    a = '_icons_/mcdonald2.png'
    b = '_icons_/boostjuice.png'
    c = '_icons_/duckrice.png'
    d = '_icons_/subway_logo.png'
    e = '_icons_/bakery.png'
    f = '_icons_/mrbean.png'

    #these are the names of the different screen 
    n1 = 'mcdonald_screen'
    n2 = 'boost_screen'
    n3 = 'duck_screen'
    n4 = 'subway_screen'
    n5 = 'bakery_screen'
    n6 = 'mrbean_screen'

    arraylist = [[a,n1],[b,n2],[c,n3],[d,n4],[e,n5],[f,n6]]
    self.layout2 = GridLayout(rows=2, spacing = 50,size_hint = (0.95,0.5), 
                   pos_hint = {"top":.65,"x":0},padding=(90,0,50,0))
    for image in arraylist:
        self.image_outlet = ImageButton(
            size_hint=(1, 0.1), 
            source= image[0])

        self.screen_name = image[1]
        self.image_outlet[0].bind(on_release= ??) ## This part is the one  
                                                     i want to change 
                                                     according to the 
                                                     different screen
        self.layout2.add_widget(self.image_outlet)
    self.add_widget(self.layout2)


GUI = Builder.load("_kivy_/trying.kv")
class TRYINGApp(App):
    def build(self):
        return GUI
    def change_screen(self,screen_name):
        screen_manager = self.root.ids['screen_manager']
        screen_manager.current = screen_name

#kv file#
# all the varies kv file screen
#: include _kivy_/variestime_screen.kv
#: include _kivy_/homescreen.kv
#: include _kivy_/mcdonaldscreen.kv
#: include _kivy_/firstpage.kv
#: include _kivy_/mrbeanscreen.kv
#: include _kivy_/boostscreen.kv
#: include _kivy_/duckscreen.kv
#: include _kivy_/subwayscreen.kv
#: include _kivy_/bakeryscreen.kv


GridLayout:
    cols:1
    ScreenManager:
        id : screen_manager
        FirstPage:
            name :"first_page"
            id : first_page

        VariesTimeScreen:
            name: "variestime_screen"
            id: variestime_screen

        HomeScreen:
            name : "home_screen"
            id : home_screen

        McDonaldScreen:
            name : "mcdonald_screen"
            id : mcdonald_screen

        BoostScreen:
            name : "boost_screen"
            id : boost_screen

        DuckScreen:
            name: "duck_screen"
            id: duck_screen

        SubwayScreen:
            name:"subway_screen"
            id: subway_screen

        BakeryScreen:
            name: "bakery_screen"
            id: bakery_screen

        MrBeanScreen:
            name: "mrbean_screen"
            id : mrbean_screen

Solution

  • Your on_release can be something like:

    self.image_outlet.bind(on_release=partial(self.change_screen, image[1]))
    

    where change_screen is a method that you must define:

    def change_screen(self, new_screen_name, button_instance):
        # some code to change to the screen with name new_screen_name
    

    Note that I have removed the [0] from self.image_outlet (I suspect that was a typo). I can't determine what code should go in the new method, because you haven't provided enough information.

    If you have a change_screen method in your App class, you can use that directly by referencing it in your on_release as:

    self.image_outlet.bind(on_release=partial(App.get_running_app().change_screen, image[1]))
    

    You will need to make a minor change to your change_screen method to handle additional args:

    def change_screen(self, screen_name, *args):
        screen_manager = self.root.ids['screen_manager']
        screen_manager.current = screen_name