Call function from class from function outside class

645 views
Skip to first unread message

Kamil Widzyk

unread,
Jun 23, 2021, 7:26:48 AM6/23/21
to Kivy users support
Hi, I have simple app with two screens with button to switch between them and a label with value. I want every second to increase value on first label and decrease value on second label. I already have 'loop' called every second and functions in classes to increase and decrease values, but I have no idea how to call these functions. I posting my code below:

main.py:

from kivy.app import App
from kivy.clock import Clock
from kivy.uix.screenmanager import ScreenManager, Screen

value1 = 0
value2 = 0

def loop(data):
    # This function is called every 1s by Clock
    # I want to call 'increase' function from 'test1' class
    # and 'decrease' function from 'test2' class

    pass

class test1(Screen):
    def increase(self):
        global value1
        value1 += 1
        self.label1.text = "Increasing: " + str(value1)

class test2(Screen):
    def decrease(self):
        global value2
        value2 -= 1
        self.label2.text = "Decreasing: " + str(value2)

class MainWindow(App):
    def build(self):
        sm = ScreenManager()
        sm.add_widget(test1(name="test1"))
        sm.add_widget(test2(name="test2"))
        return sm

Clock.schedule_interval(loop, 1)
MainWindow().run()

 mainwindow.kv:

#: import FadeTransition kivy.uix.screenmanager.FadeTransition
<test1>:
    label1: label1
    BoxLayout:
        Button:
            text: "Go to test2"
            size_hint: 0.5, 0.1
            on_release:
                app.root.transition = FadeTransition(duration=0.1)
                root.manager.current = "test2"
        Label:
            id: label1
            text: "Increasing: 0"

<test2>:
    label2: label2
    BoxLayout:
        Button:
            size_hint: 0.5, 0.1
            text: "Go to test1"
            on_release:
                app.root.transition = FadeTransition(duration=0.1)
                root.manager.current = "test1"
        Label:
            id: label2
            text: "Decreasing: 0"


Elliot Garbus

unread,
Jun 23, 2021, 10:57:33 AM6/23/21
to kivy-...@googlegroups.com

I have made a number of changes to your code.

I combined the kv code and python code into one file, this is to simplify sharing.  This uses Builder.

I moved the 2 global variables value1 and value2 to their respective screens.  These values ‘belong’ to the screen, so it make sense to have them be in the class.  I used kivy numeric properties to declare these variables.

The kv code was changed to use the kivy NumericProperties.

I moved the ScreenManger and instancing of the screens to kv.

I moved the loop method to be under app, and the Clock.schedule_interval to be called from on_start().

 

In loop the methods are accessed as:

        self.root.get_screen('test1').increase()
              self is App

root is the ScreenManager

get_screen() returns the screen widget.

 

Hope that makes sense.

 

from kivy.app import App
from kivy.lang import Builder   # moved all to on file to simplify posting
from kivy.clock import Clock
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import NumericProperty  # use for values

kv = """

#: import FadeTransition kivy.uix.screenmanager.FadeTransition
<test1>:
    label1: label1
    BoxLayout:
        Button:
            text: "Go to test2"
            size_hint: 0.5, 0.1
            on_release:
                app.root.transition = FadeTransition(duration=0.1)
                root.manager.current = "test2"
        Label:
            id: label1
            text: "Increasing: " + str(root.value1)  # printing the property


<test2>:
    label2: label2
    BoxLayout:
        Button:
            size_hint: 0.5, 0.1
            text: "Go to test1"
            on_release:
                app.root.transition = FadeTransition(duration=0.1)
                root.manager.current = "test1"
        Label:
            id: label2
            text: "Decreasing: " + str(root.value2)  # printing from the property

ScreenManager:
    Test1:
        name: 'test1'
    Test2:
        name: 'test2'

"""

# value1 = 0  ### These values are associated with the screens - that is where they belong
# value2 = 0


class Test1(Screen):
    value1 = NumericProperty()

   
def increase(self):
       
self.value1 += # use the property


class Test2(Screen):
    value2 = NumericProperty()

   
def decrease(self):
       
self.value2 -= 1

class MainWindow2(App):
   
def build(self):
       
# sm = ScreenManager()  # moved this code to kv
        # sm.add_widget(test1(name="test1"))
        # sm.add_widget(test2(name="test2"))
        # return sm
       
return Builder.load_string(kv)

   
def on_start(self):
        Clock.schedule_interval(
self.loop, 1)

   
def loop(self, dt):  # moved into app, out of global scope

        # This function is called every 1s by Clock
        # I want to call 'increase' function from 'test1' class
        # and 'decrease' function from 'test2' class
        self.root.get_screen('test1').increase()
       
self.root.get_screen('test2').decrease()


MainWindow2().run()

--
You received this message because you are subscribed to the Google Groups "Kivy users support" group.
To unsubscribe from this group and stop receiving emails from it, send an email to kivy-users+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/kivy-users/a6103e78-dca4-4a17-9e12-35e71ab784c1n%40googlegroups.com.

 

Kamil Widzyk

unread,
Jun 23, 2021, 11:32:14 AM6/23/21
to Kivy users support

@ElliotG, Big thanks to you. Code works perfect. Thanks you again!
Reply all
Reply to author
Forward
0 new messages