Esoteric Tech
Esoteric Tech

Reputation: 31

Kivy- Call method outside of class

I have 2 buttons and 2 labels in my .kv file

<Controller>:
    lbl1: first_check
    lbl2: second_check

BoxLayout:
    orientation: 'horizontal'


    Button:
        on_press: root.start_program()
        text: 'Start Program'


    Button:
        on_press: root.stop_program()
        text: "Stop Program"


    Label:
        id: first_check
        text: 'No distance given'

    Label:
        id: second_check
        text: 'No distance given'

In the .py file I have the root widget Controller class and some additional functions check_distance and end_goal outside of the class

def check_distance(dt):
"""The if statements in this block of code will be run if r.dist <= 2700"""
c = Controller()
r.loop()
print(r.dist)
if r.dist <= 2700:
    c.show_dist()
    time.sleep(0.5)
    r.loop()
    if r.dist <= 2700:
        c.lbl2.text = "Below 2700"
        end_goal()

def end_goal():
"""Stops the check_distance function from being called every 2 seconds then 
runs the next bit of code"""
    Clock.unschedule(check_distance)
    beepPin.write(1)
    time.sleep(1)
    beepPin.write(0)
    time.sleep(1)
    beepPin.write(1)
    time.sleep(1)
    beepPin.write(0)    

class Controller(BoxLayout):
    def __init__(self, **kwargs):
        super(Controller, self).__init__(**kwargs)



def start_program(self):
    """Tells the check_distance function to run every 2 seconds"""
    Clock.schedule_interval(check_distance, 2)



def stop_program(self):
    """Will stop the check_distance function from running"""
    Clock.unschedule(check_distance)
    self.lbl2.text = str(r.dist)

def show_dist(self):
    self.lbl1.text = str(r.dist)

class BaseMotorApp(App):
    def build(self):
        return Controller()

BaseMotorApp().run()

When the Start Program button is pushed the check_distance function gets called every 2 seconds. Once the if conditions are met it will run through all the check_distance code. I know this is happening because the end_goal is successfully called. The problem is c.show_dist() is not doing anything and I'm not getting any error. I want it to call the show_dist function in the Controller class. I've even tried to eliminate the show_dist function all together and just typed self.lbl1.text = str(r.dist) in the check_distance function but still nothing. I'm guessing there must be some problem with the way that I am calling this class method. Can someone please help me?

Upvotes: 1

Views: 1111

Answers (1)

ikolim
ikolim

Reputation: 16041

Avoid time.sleep in Kivy applications

The problem that you are encountering was due to time.sleep. You should replace time.sleep with Kivy Clock.schedule_once as in the following exmple.

def check_distance(dt):
    """The if statements in this block of code will be run if r.dist <= 2700"""
    c = Controller()
    r.loop()
    print(r.dist)
    if r.dist <= 2700:
        c.show_dist()
        Clock.schedule_once(check_distance_assign_label, 0.5)


def check_distance_assign_label(dt):
    r.loop()
    if r.dist <= 2700:
        c.lbl2.text = "Below 2700"
        end_goal()


def end_goal():
    """Stops the check_distance function from being called every 2 seconds then
    runs the next bit of code"""
    Clock.unschedule(check_distance)
    Clock.schedule_once(beepPinWrite(0), 1.0)
    Clock.schedule_once(beepPinWrite(1), 2.0)
    Clock.schedule_once(beepPinWrite(0), 3.0)


def beepPinWrite(index, dt):
    beepPin.write(index)

Upvotes: 2

Related Questions