How to get Id and Text value of a kivy button as string?

13,339

First, you must pass the button instance explicitly to the method when it is called from the kv:

on_press: app.Pressbtn(self)

You can then use the instance reference to modify the button or see its attributes, you do not need the id. If you want to get the id, you can only do it using the ids dictionary of the button parent.

An example based on your code:

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder

kv_file = '''
<MyButton@Button>:
    color: .8,.9,0,1
    font_size: 32

<KVMyHBoxLayout>:
    orientation: 'vertical'
    MyButton:
        id:"idBtn1"
        text: "Btn1"
        background_color: 1,0,0,1
        on_press:app.Pressbtn(self)
    MyButton:
        id:"idBtn2"
        text: "Btn2"
        background_color: 0,1,0,1
        on_press:app.Pressbtn(self)
    Label:
        id: lobj
        text: "Object"
        background_color: 1,0,1,1

    Label:
        id: lid
        text: "ID"
        background_color: 0,0,1,1
    Label:
        id: ltext
        text: "Text"
        background_color: 1,0,1,1
'''


class KVMyHBoxLayout(BoxLayout):
    pass

class ExampleApp(App):
    def Pressbtn(self, instance):
        instance.parent.ids.lobj.text = str(instance)
        instance.parent.ids.ltext.text = instance.text
        instance.parent.ids.lid.text= self.get_id(instance)

    def get_id(self,  instance):
        for id, widget in instance.parent.ids.items():
            if widget.__self__ == instance:
                return id

    def build(self):
        Builder.load_string(kv_file)
        return KVMyHBoxLayout()

if __name__ == "__main__":
    app = ExampleApp()
    app.run()

Output:

enter image description here

Edit:

If you define the widget (button) in the .py file you do not need to pass the instance to the function, it is passed automatically as argument:

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.button import Button
from kivy.uix.scrollview import ScrollView


class FirstScreen(Screen):
    def __init__(self,**kwargs):
        super(FirstScreen, self).__init__(**kwargs)    
        layout=BoxLayout(orientation="vertical",size_hint_y= None)
        layout.bind(minimum_height=layout.setter('height'))                
        for i in range(50):
                btn = Button(text="Button"+str(i),
                             id=str(i),
                             size_hint=(None, None),
                             on_press=self.Press_auth)               #<<<<<<<<<<<<<<<<           
                layout.add_widget(btn)
        root = ScrollView()
        root.add_widget(layout)
        self.add_widget(root)

    def Press_auth(self,instance):     
        print(str(instance))

class TestScreenManager(ScreenManager):
    def __init__(self,  **kwargs):
        super(TestScreenManager,  self).__init__(**kwargs)
        self.add_widget(FirstScreen())

class ExampleApp(App):
    def build(self):           
        return TestScreenManager()

def main():
    app = ExampleApp()
    app.run()

if __name__ == '__main__':
    main()
Share:
13,339

Related videos on Youtube

Eka
Author by

Eka

Blah Blah Blah

Updated on June 04, 2022

Comments

  • Eka
    Eka almost 2 years

    I have an app with multiple buttons and I need to get id and text value of the button as string when it is pressed. The grabbed Ids and Text valus of the button will then be passed to another function for further processing. For simplicity I wrote this sample programme.

    # main.py
    
    from kivy.app import App
    from kivy.uix.boxlayout import BoxLayout
    
    ########################################################################
    class KVMyHBoxLayout(BoxLayout):
        pass
    
    
    ########################################################################
    class ExampleApp(App):
        def Pressbtn(self, *args):
            print'Pressed button'
        #----------------------------------------------------------------------
        def build(self):
    
            return KVMyHBoxLayout()
    
    #----------------------------------------------------------------------
    if __name__ == "__main__":
        app = ExampleApp()
        app.run()
    

    kv file

    <MyButton@Button>:
        color: .8,.9,0,1
        font_size: 32
    
    <KVMyHBoxLayout>:
        orientation: 'vertical'
        MyButton:
            id:"idBtn1"
            text: "Btn1"
            background_color: 1,0,0,1
            on_press:app.Pressbtn()
        MyButton:
            id:"idBtn2"
            text: "Btn2"
            background_color: 0,1,0,1
            on_press:app.Pressbtn()
        Label:
            text: "ID"
            background_color: 0,0,1,1
        Label:
            text: "Text"
            background_color: 1,0,1,1
    

    When a button is pressed its corresponding values of id and text will be shown in the ID and Text labels. Currently the above code only print Pressed button when button is pressed. I want to know how to get id and text value of button pythonically.

  • Eka
    Eka almost 7 years
    Thanks it works I am using button inside a screen when I press button it returns screen's object <Screen name='FirstScreen''> any idea how to get buttons instance which is inside a layout inside the screen.
  • FJSevilla
    FJSevilla almost 7 years
    @Eka this code works even if the button is inside a layout inside a Screen (except to get the id). If you can´t make it work properly, edit the question by adding the code to see if I can help you. Best regards.
  • Eka
    Eka almost 7 years
    This is my code pastebin.com/PDQpXbkU I am creating a Scrollview boxlayout with button dynamically in the screen class. This on_press=lambda a:self.Press_auth(self) i took it from some sample code and it detects press event but the object its passing is <Screen name='FirstScreen''>
  • FJSevilla
    FJSevilla almost 7 years
    @Eka you only need to replace on_press = lambda to: self.Press_auth (self) with on_press=self.Press_auth. I edited the answer. Best regards.
  • Eka
    Eka almost 7 years
    Thanks it solved my problem. initially I tried this on_press=self.Press_auth() . it throwed me an error. once more thank you