Kivy: How to access global variables in .kv file

Question:

I’m fairly new to kivy and need some help with accessing a global variable in kivy. The idea of this demo code is to be able to update a global variable via a class method. These methods would, in practice, be buttons that a user presses that update the variable. I want to know how I can access this new variable depending on which function is used. IMPORTANT NOTE: These methods cannot be accessed via ClassA().CA2().x as in practice they would have too many parameters to navigate. Is there an alternative method that allows me to access the updated variable without having to access the method directly?

Python File:

from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import StringProperty

x = 0

class ClassA():
    def CA1(self):
        global x
        x = 1

    def CA2(self):
        global x
        x = 2

    def CA3(self):
        global x
        x = 3

    def CA4(self):
        global x
        x = 4

class ClassB(Screen):
    y = StringProperty(x)

ClassA().CA3()

ClassB()

class WindowManager(ScreenManager):
    pass

sm = WindowManager()

class unknown_class_method(App):
    def build(self):
        sm.add_widget(ClassB(name='CB'))
        sm.current = 'CB'
        return sm

if __name__ == '__main__':
    unknown_class_method().run()

Kivy File:

<ClassB>:
    Label:
        text: str(int(root.y))
Asked By: Griffin Neal

||

Answers:

root refers to ClassA, not main.py. Therefore x must be a property of the class, not a local variable. Here is the code that does what you are looking for.

from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.gridlayout import GridLayout


class ClassA(GridLayout):
    def CA1(self):
        self.x = 1

    def CA2(self):
        self.x = 2

    def CA3(self):
        self.x = 3

    def CA4(self):
        self.x = 4


class MyApp(App):
    def build(self):
        return ClassA()


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

#Note: You must name the kivy file my.kv for it to work since from the code I refer to it as class MyApp(App):

<ClassA>:
cols: 1

Label:
    id: MyLabel
    text: str(int(root.x))


Button:
    text: "CA1"
    on_press:root.CA1()
    on_release:
        MyLabel.text = str(int(root.x))

Button:
    text: "CA2"
    on_press:root.CA2()
    on_release:
        MyLabel.text = str(int(root.x))

Button:
    text: "CA3"
    on_press:root.CA3()
    on_release:
        MyLabel.text = str(int(root.x))

Button:
    text: "CA4"
    on_press:root.CA4()
    on_release:
        MyLabel.text = str(int(root.x))
Answered By: Genaro.exe

You can either have a real global variable at module-level:

# global namespace
global_var = "This is global."

But you wouldn’t want that.

OR

You can have an "app-level" global variable:

class MyApp(App):
    def __init__(self, **kwargs):
        self.app_var = "This is app-instance variable."
        global app
        app = self # equivalent to App.get_running_app()
        # or you may choose not to use this and declare
        # it on other classes the longer way via App.get_running_app(). 


    def build(self):
        return ClassA()

Where you could access it from other classes via:

class ClassA(GridLayout):
    def CA1(self):
        self.x = app.app_var
        # or App.get_running_app().app_var

    def CA2(self):
        self.x = app.app_var
        # or App.get_running_app().app_var
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.