Search code examples
pythonkivykivy-language

Is there a way to change kivy api variables (e.g. scroll_distance) inside kv file?


I recently started learning kivy and don't fully understand how the interaction between .kv file and python file works. For example,

class TimelineScr(ScrollView):
    scroll_wheel_distance = 60

If I want to change this variable inside

<TimelineScr>:
    Label:
        canvas.before:
            Color:
                rgb: define.LIGHT_BLUE
            Rectangle:
                pos: self.pos
                size: root.width, self.texture_size[1]
            Color:
                rgb: (0.78, 0.92, 0.91)
            Rectangle:
                size: root.width-40, self.texture_size[1]-40
                pos: 20, 20

        size_hint_y: None
        height: self.texture_size[1]
        padding_y: 40
        #shorter: True
        line_height: 2

        color: define.TEXT_GREEN
        font_size: 20
        font_name: 'src/fonts/static/Inter-Regular.ttf'

        text: str(main.timeline)
        text_size: (root.width - 80, None)

can I do it and how?

Sorry for my English


Solution

  • I am not really a pro with kivy but here is with what i often start: i have a main.py like this:

    import # what u need
    
    Builder.load_file('the.kv')
        
    class fscreen(Widget):
        def __init__(self, **kwargs):
            super().__init__(**kwargs)
            
    
    
    class secscreen(Widget):
    
        def __init__(self,**kwargs):
            super().__init__(**kwargs)
            pass
    
    class thscreen(Widget):
        def __init__(self,**kwargs):
            super().__init__(**kwargs)
            pass
                
    class theapp(App):
        def build(self):
            self.screenm = ScreenManager()
    
            self.fscreen = fscreen()
            screen = Screen(name = "first screen")
            screen.add_widget(self.fscreen)
            self.screenm.add_widget(screen)
    
            self.secscreen = secscreen()
            screen  = Screen(name = "secondscreen")
            screen.add_widget(self.secscreen)
            self.screenm.add_widget(screen)
    
            self.thscreen = thscreen()
            screen  = Screen(name = "thirdscreen")
            screen.add_widget(self.thscreen)
            self.screenm.add_widget(screen)
            return self.screenm
    
    if __name__ == "__main__":
        theapp = theapp()                                       
        theapp.run() 
    

    and a the.kv like this:

    <fscreen>
            
        canvas.before:
            Color:
                rgba: 1, 1, 1, 1
        
            Rectangle:
                size: root.width, root.height
                pos: 0, 0
        
        
        
        ScrollView:
            id: scroll_view
            size: root.width*0.4, root.height*0.4
            pos: root.height*0.3, root.height*0.3
            Label:
                id: output
                color: 0, 0, 0, 1
                text: ''
                size_hint_x: 1.0
                size_hint_y: None
                text_size: self.width, None
                height: self.texture_size[1]
    

    now if i want to change the label thats in the the.kv file there is two ways of changing it:

    1. by id: for that we demonstration purpose we have to add a Button in our kv file in our <fscreen> and a function in our main.py like this:

    in the.kv file:

    Button:
        text: ' change label by id'
        size: root.width*0.4, root.height*0.05
        pos: root.width*0.3, root.height*0.1
        on_press: root.change_label()
    

    in main.py:

    def change_label(self):
        self.ids.output.text = 'label has been changed by id'
    

    same if we want to change ScrollView by id:

    the ScrollView id takes a lot of attributes same as the label for example lets say we have another Button and another function as shown before we can change anything by id like this:

    def change_by_id(self):
        self.ids.scroll_view.size[0] = self.width*0.5   
        self.ids.scroll_view.size[1] = self.height*0.5 
    
        self.ids.scroll_view.pos[0] = self.width*0.25   
        self.ids.scroll_view.pos[1] = self.height*0.25
        self.ids.scroll_view.#valid attribute = ...
    
        self.ids.output.text = 'something'
        self.ids.output.font_size = #....
        self.ids.output.color = #....    # and so on
    
    1. by properties:

    for this lets change something in the the.kv file:

        ScrollView:
            id: scroll_view
            size: root.width*0.4, root.height*0.4
            pos: root.height*0.3, root.height*0.3
            Label:
                id: output
                color: 0, 0, 0, 1
                text: root.string   ###### this is what we changed
                size_hint_x: 1.0
                size_hint_y: None
                text_size: self.width, None
                height: self.texture_size[1]
    
            Button:
                text: ' change label by prop'
                size: root.width*0.4, root.height*0.05
                pos: root.width*0.3, root.height*0.1
                on_press: root.change_by_prop()
    

    now the main.py has to have a string property like this:

    class fscreen(Widget):
        string = StringProperty()
        def __init__(self, **kwargs):
            super().__init__(**kwargs
            self.string = ''
       
        def change_by_prop(self):
            self.string = 'text has been changed by property'
    

    and ofc there are many properties NumericProperty(), StringProperty() and so on ...

    this is how I change things in kv file from python main.