How to schedule a schedule with kivy

0

I want to make an event occur for 2 seconds at the speed of 29/30, after 5 seconds from the start of the program, with the following code:

from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.clock import *

class LoginScreen(GridLayout):
    def __init__(self, **kwargs):
        super(LoginScreen, self).__init__(**kwargs)
        self.cols = 2
        self.add_widget(Label(text='User Name'))
        self.username = TextInput(multiline=False)
        self.add_widget(self.username)
        self.add_widget(Label(text='password'))
        self.password = TextInput(password=True, multiline=False)
        self.add_widget(self.password)

stop= 0

class MyApp(App):

    def build(self):

        return LoginScreen()

    def my_callback(dt):
        global stop
        if stop == 1:
            print ('Last call of my callback, bye bye !')
            return False
        print ('My callback is called')

    def stop_my_callback(dt):
        global stop
        stop = 1

    def start_my_callback(dt):
        event = Clock.schedule_interval(my_callback, 29 / 30.)
        Clock.schedule_once(stop_my_callback, 2)

    Clock.schedule_once(start_my_callback, 5)

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

However, after 5 seconds, the console returns:

 Traceback (most recent call last):
   File "C:\Users\enzo\Desktop\teste.py", line 44, in <module>
     MyApp().run()
   File "C:\Users\enzo\AppData\Local\Programs\Python\Python37\lib\site-packages\kivy\app.py", line 826, in run
     runTouchApp()
   File "C:\Users\enzo\AppData\Local\Programs\Python\Python37\lib\site-packages\kivy\base.py", line 502, in runTouchApp
     EventLoop.window.mainloop()
   File "C:\Users\enzo\AppData\Local\Programs\Python\Python37\lib\site-packages\kivy\core\window\window_sdl2.py", line 727, in mainloop
     self._mainloop()
   File "C:\Users\enzo\AppData\Local\Programs\Python\Python37\lib\site-packages\kivy\core\window\window_sdl2.py", line 460, in _mainloop
     EventLoop.idle()
   File "C:\Users\enzo\AppData\Local\Programs\Python\Python37\lib\site-packages\kivy\base.py", line 337, in idle
     Clock.tick()
   File "C:\Users\enzo\AppData\Local\Programs\Python\Python37\lib\site-packages\kivy\clock.py", line 581, in tick
     self._process_events()
   File "kivy\_clock.pyx", line 384, in kivy._clock.CyClockBase._process_events
   File "kivy\_clock.pyx", line 414, in kivy._clock.CyClockBase._process_events
   File "kivy\_clock.pyx", line 412, in kivy._clock.CyClockBase._process_events
   File "kivy\_clock.pyx", line 167, in kivy._clock.ClockEvent.tick
   File "C:\Users\enzo\Desktop\teste.py", line 38, in start_my_callback
     event = Clock.schedule_interval(my_callback, 29 / 30.)
 NameError: name 'my_callback' is not defined

How can I resolve this?

    
asked by anonymous 09.12.2018 / 21:04

1 answer

1

When defining methods of a class, the first parameter is always the instance of the class being used to call the method, and is passed automatically by python. By convention, the name self is used:

def my_callback(self, dt):
    ...
def stop_my_callback(self, dt):
    ...
def start_my_callback(self, dt):
    ...

One of the advantages of using classes is that you no longer need to use globals, avoiding all the confusion they may cause. Instead, it is possible to store data according to the context, through attributes of the class or its instances. In the example below we can use an instance attribute through self.stop :

def start_my_callback(self, dt):
    self.stop = 0
    ...

def stop_my_callback(self, dt):
    self.stop = 1

def my_callback(self, dt):
    if self.stop == 1:
        ...

Another change is when it comes to a method. After defining a class, the methods become attributes of the instances. Thus, if you are within a method of the class, you can again use self to get reference to another method, in example self.my_callback :

def start_my_callback(self, dt):
    self.event = Clock.schedule_interval(self.my_callback, 29 / 30.)
    Clock.schedule_once(self.stop_my_callback, 2)
    
10.12.2018 / 02:42