1
votes

I have a ScrollView, in which there is a GridLayout, in which there are 10 buttons. I can't fix my problem: all the buttons are added to the grid layout by using only the python file (no .kv) so i need to add a "on_press: something" when i create each button. I want each button to print its name (the 'text: something' property) when clicked.

debug.kv

#: kivy 1.9.1

<AppScreenManager>:
    Home:

Home:

debug.py

from kivy.app import App
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.core.window import Window
from kivy.uix.button import Button
from kivy.uix.scrollview import ScrollView
from kivy.uix.gridlayout import GridLayout
from kivy.lang import Builder

class AppScreenManager(ScreenManager):
    def __init__(self, **kwargs):
        super(AppScreenManager, self).__init__(**kwargs)

class Home(Screen):

    def __init__(self, **kwargs):
        super(Home, self).__init__(**kwargs)
        self.myinit()

    # function that loads 10 buttons on the Home menu (in a ScrollView) when it is launched
    def myinit(self):

        # create some strings
        numbers = [str(i) for i in range(1, 11)]

        # The scrollview will contain this grid layout
        self.layout = GridLayout(cols=1, padding=5, spacing=5, size_hint=(1,None))
        # I don't know why do this line exists but it works x)
        self.layout.bind(minimum_height=self.layout.setter('height'))

        # create 10 buttons
        for number in numbers:
            ### My problem is HERE, under this line, with the on_press property ###
            btn = Button(text=number, on_press=print number, background_color=(.7, .7, .7, 1), color=(1,1,1,1), size=(32,32), size_hint=(1, None))
            # add the button to the grid layout
            self.layout.add_widget(btn)

        # create the scroll view
        self.scrll = ScrollView(size_hint=(1, .6), pos_hint={'center_x': .5, 'center_y': .5}, do_scroll_x=False)
        # add the grid layout to the scroll view
        self.scrll.add_widget(self.layout)
        # add everything (the scroll view) to the HOME menu
        self.add_widget(self.scrll)




class MyAppli(App):

    def build(self):
        Window.clearcolor = (1,1,1,1)
        return AppScreenManager()

Builder.load_file("debug.kv")
if __name__ == '__main__':
    MyAppli().run()
2

2 Answers

1
votes

Callable you pass to on_press will receive button instance as it's param:

class Home(Screen):
    def button_pressed(self, btn):
        print(btn.text)

    # ...

and

Button(text=number, on_press=self.button_pressed,  # ...
0
votes

Other (and IMHO better) way: you can create your own class MyButton as child of the Button class and define on_press() method:

class MyButton(Button):

    numeric_property = NumericProperty(0)

    def __init__(self, numeric_property, **kwargs):
        super(MyButton, self).__init__(**kwargs)
        self.numeric_property = numeric_property

    def on_press(self):
        print self.numeric_property

And then you can add it:

for number in numbers:
    btn = MyButton(text=number, numeric_property=number, background_color=(.7, .7, .7, 1), color=(1,1,1,1), size=(32,32), size_hint=(1, None))
    self.layout.add_widget(btn)