Filip Phigari
Filip Phigari

Reputation: 135

Reference ID of Dynamically Created Widget through On_Press Event in Python

Question:

How do I reference the id of a widget dynamically created in Python through an On_Press event?

Goal:

When clicking on dynamically created buttons, 'Test 1', 'Test 2', or 'Test 3', I want that button's id to print.

More specifically, I want that id to print from the def changer(self, *args) method

Problem:

As you can probably guess from looking at code provided, I am only able to print the id of the last created button ('Test 3').

Python Code:

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.clock import Clock
from kivy.uix.widget import Widget
from functools import partial

class ScrollableLabelDataEntryInstructions(BoxLayout):
    pass

class NewGarageScreen(Screen):
    pass

class ContinueEditingScreen(Screen):
    pass

class GarageNameBoxLayout(BoxLayout):
    LatestID = "initial"
    def __init__(self, **kwargs):
        super(GarageNameBoxLayout, self).__init__(**kwargs)
        self.orientation = "vertical"
        Clock.schedule_interval(self.create_button, 5)

    def create_button(self, *args):
        self.box_share2.clear_widgets()
        app = App.get_running_app()
        sm = app.root

        #put GarageNameStartList data into app class, then pull from it in this class
        top_button_share = 1.1
        color = (.4, .4, .4, 1)
        for text in app.GarageNameStartList:
            top_button_share -= .4
            id_ = text
            self.LatestID = id_
            button_share = Button(background_normal='',
                                  background_color = color,
                                  id = id_,
                                  pos_hint = {"x": 0, "top": top_button_share},
                                  size_hint_y = None,
                                  height = 60,
                                  font_size = 30,
                                  text = text)
            button_share.bind(on_press = self.changer)
            button_share.bind(on_press = lambda *args: setattr(sm, 'current', "newgarage"))
            self.box_share2.add_widget(button_share)

    def changer(self,*args):
        print(self.LatestID)

class BackHomeWidget(Widget):
    pass

class MainScreen(Screen):
    pass

class AnotherScreen(Screen):
    pass

class ScreenManagement(ScreenManager):
    pass

presentation = Builder.load_file("example_on_press.kv")

class MainApp(App):
    GarageNameStartList = ["Test1", "Test2", "Test3"]

    def Update_GarageNameStartList(self, *args):
        self.GarageNameStartList = ["Test1", "Test2", "Test3"]   


    def build(self):
        return presentation

if __name__ == "__main__":
    MainApp().run()

Kv Code:

#: import FadeTransition kivy.uix.screenmanager.FadeTransition

ScreenManagement:
    transition: FadeTransition()
    MainScreen:
    AnotherScreen:
    NewGarageScreen:
    ContinueEditingScreen:

<SmallNavButton@Button>:    
    font_size: 32
    size: 125, 50    
    color: 0,1,0,1

<MedButton@Button>:
    font_size: 30
    size_hint: 0.25, 0.1
    color: 0,1,0,1

<BackHomeWidget>:
    SmallNavButton:
        on_release: app.root.current = "main"
        text: "Home"
        pos: root.x, root.top - self.height

<MainScreen>:
    name: "main"
    FloatLayout: 
        MedButton:
            on_release: app.root.current = "edit"
            text: "Edit"
            pos_hint: {"x":0.3728, "top": 0.4}

<AnotherScreen>:
    name: "edit"
    BackHomeWidget:
        SmallNavButton:
            on_release: app.root.current = "main"
            text: "Back"
            pos: root.x, root.top - (2.25*(self.height))
    FloatLayout:
        MedButton:
            on_release: app.root.current = "continueediting"
            text: "Continue Editing"
            pos_hint: {"x":0.25, "top": 0.6} 
        MedButton:
            on_release: app.root.current = "newgarage"
            text: "Create New"
            pos_hint: {"x":0.3728, "top": 0.4}

<NewGarageScreen>:
    name: "newgarage"
    BackHomeWidget:
        SmallNavButton:
            on_release: app.root.current = "edit"
            text: "Back"
            pos: root.x, root.top - (2.25*(self.height))
    FloatLayout:
        MedButton:
            text: "1. Groundfloor"
            pos_hint: {"x":0, "top": 0.6}


<GarageNameBoxLayout>:
    box_share2: box_share2
    ScrollView:
        GridLayout:
            id: box_share2
            cols: 1
            size_hint_y: None
            size_hint_x: 0.5
            spacing: 5
            padding: 130
            height: self.minimum_height
            canvas:
                Color: 
                    rgb: 0, 0, 0
                Rectangle:
                    pos: self.pos
                    size: self.size         

<ContinueEditingScreen>:
    name: "continueediting"
    GarageNameBoxLayout:
    BackHomeWidget:
        SmallNavButton:
            on_release: app.root.current = "edit"
            text: "Back"
            pos: root.x, root.top - (2.25*(self.height))

Upvotes: 0

Views: 566

Answers (1)

eyllanesc
eyllanesc

Reputation: 243955

when you use bind(), the first parameter that passes is the instance that issues the event, so in your case instance is the Button, and then we can access the id:

def changer(self, instance):
    print(instance.id)

Upvotes: 1

Related Questions