title: KIVY - Python Keep doing while button is pressed
body: <p>I'm currently trying to make a platformer game for IOS/Android but I'm stuck on a problem. I've created two buttons and a character. I want the character to keep moving until the button is released. By that I mean: I can move the character once, when the button is pressed, but I want it to keep moving until the button is released.</p>
  
  <p>I've tried multiple solution, for example I used pythons time module:</p>
  
  <pre><code>class Level1(Screen):
      posx = NumericProperty(0)
      posy = NumericProperty(0)
      moving = True
      i = 0
      def __init__(self, **kwargs):
          super(Level1, self).__init__(**kwargs)
  
      def rightmove(self):
          self.posx = self.posx+1
          time.sleep(10)
  
      def goright(self):
          while self.moving == True:
              self.rightmove()
              i += 1
              if i == 10:
                  break
  
  
      def stopright(self):
          self.moving == False
  </code></pre>
  
  <p>but it doesn't work.
  It think that it somehow is put in an endless loop, because when I press the button the app stop working ("app stopped working..." error).</p>
  
  <p>I have pretty much no idea how I can fix this. I've been trying for the last few hours and havn't found a solution yet.
  Here's my .py file:</p>
  
  <pre><code>from kivy.app import App
  from kivy.lang import Builder
  from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition,         SlideTransition
  from kivy.config import Config
  from kivy.core.window import Window
  from kivy.uix.label import Label
  from kivy.uix.image import Image
  from kivy.uix.widget import Widget
  from kivy.properties import ObjectProperty, NumericProperty
  from kivy.clock import Clock
  from kivy.uix.floatlayout import FloatLayout
  import time
  Config.set('graphics','resizable',0) #don't make the app re-sizeable
  #Graphics fix
   #this fixes drawing issues on some phones
  Window.clearcolor = (0,0,0,1.) 
  
  language = "english"
  curr1msg = 1
  
  class HomeScreen(Screen):
      pass  
  
  class OptionsScreen(Screen):
      pass
  
  class GameScreen(Screen):
      pass
  
  class LevelScreen(Screen):
      pass
  
  class Level1intro(Screen):
      global language
      global curr1msg
      if language == "english" and curr1msg == 1:
          pName = "Pedro"
          msg1 = """Hello my friend!
  My name is Pedro and I have a problem. Will you help me?
  My spanish studens have a spanish test tomorrow, but I lost the exams!
  You are the only one who can help me!"""
          cont = "Press anywhere to continue..."
      elif language == "swedish" and curr1msg == 1:
          pName = "Pedro"
          msg1 = """Hejsan!
  Jag är Pedro och jag har ett problem. Kan du hjälpa mig?
  Mina spanska-elever har ett spanskaprov imorgon men jag har tappat bort     proven!
  Du är den enda som kan hjälpa mig!"""
          cont = "Tryck på skärmen för att fortsätta..."
  
  class Level1(Screen):
          posx = NumericProperty(0)
          posy = NumericProperty(0)
          moving = True
          i = 0
          def __init__(self, **kwargs):
              super(Level1, self).__init__(**kwargs)
  
          def rightmove(self):
              self.posx = self.posx+1
              time.sleep(10)
  
          def goright(self):
              while self.moving == True:
                  self.rightmove()
                  i += 1
                  if i == 10:
                      break
  
  
          def stopright(self):
              self.moving == False
  
  
  class ScreenManagement(ScreenManager):
      pass
  
  
  presentation = Builder.load_file("main.kv")
  
  class MainApp(App):
      def build(self):
          return presentation
  
  if __name__ == "__main__":
      MainApp().run()
  </code></pre>
  
  <p>And here is my .kv file:</p>
  
  <pre><code>#: import FadeTransition kivy.uix.screenmanager.FadeTransition
  #: import SlideTransition kivy.uix.screenmanager.SlideTransition
  ScreenManagement:
      transition: FadeTransition()
      HomeScreen:
      OptionsScreen:
      LevelScreen:
      Level1intro:
      Level1:
  
  &lt;HomeScreen&gt;:
      name: 'home'
  
      FloatLayout:
          canvas:
              Rectangle:
                  source:"images/home_background.jpg"
                  size: self.size
          Image:
              source:"images/logo.png"
              allow_stretch: False
              keep_ratio: False
              opacity: 1.0
              size_hint: 0.7, 0.8
              pos_hint: {'center_x': 0.5, 'center_y': 0.9}
          Button:
              size_hint: 0.32,0.32
              pos_hint: {"x":0.34, "y":0.4}
              on_press:
                  app.root.transition = SlideTransition(direction="left")
                  app.root.current = "level"
              background_normal: "images/play_button.png"
              allow_stretch: False
          Button:
              size_hint: 0.25,0.25
              pos_hint: {"x":0.38, "y":0.15}
              on_press:
                  app.root.transition = SlideTransition(direction="left")
                  app.root.current = 'options'
              background_normal: "images/settings_button.png"
  
  &lt;OptionsScreen&gt;:
      name: 'options'
  
  &lt;LevelScreen&gt;
      name: "level"
  
      FloatLayout:
          canvas:
              Rectangle:
                  source:"images/home_background.jpg"
                  size: self.size
          Label:
              text: "[b]Choose Level[/b]"
              markup: 1
              font_size: 40
              color: 1,0.5,0,1
              pos: 0,250
          Button:
              size_hint: 0.1,0.1
              pos_hint: {"x": 0.1, "y": 0.8}
              on_press:
                  app.root.current = "level1intro"
              Image:
                  source:"images/level1.png"
                  allow_stretch: True
                  y: self.parent.y + self.parent.height - 70
                  x: self.parent.x
                  height: 80
                  width: 80
  
          Button:
              background_normal: "images/menu_button.png"
              pos_hint: {"x": 0.4, "y": 0}
              size_hint: 0.3,0.3
              pos_hint: {"x": 0.35}
              on_press:
                  app.root.transition = SlideTransition(direction="right")
                  app.root.current = "home"
  
  &lt;Level1intro&gt;
      name: "level1intro"
  
      canvas:
          Rectangle:
              source: "images/background.png"
              size: self.size
      Image:
          source: "images/dialog.png"
          pos_hint: {"y": -0.35}
          size_hint: 0.7,1.0
      Label:
          font_size: 20
          color: 1,1,1,1
          pos_hint: {"x": -0.385, "y": -0.285}
          text: root.pName
      Label:
          font_size: 15
          color: 1,1,1,1
          pos_hint: {"x": -0.15, "y": -0.4}
          text: root.msg1
      Label:
          font_size: 15
          color: 0.7,0.8,1,1
          pos_hint: {"x": 0.025, "y": -0.449}
          text: root.cont
          on_touch_down: 
              app.root.transition = FadeTransition()
              app.root.current = "level1"
  
  &lt;Level1&gt;
      name: "level1"
      canvas:
          Rectangle:
              source: "images/background.png"
              size: self.size
  
      Button:
          text: "&gt;"
          size_hint: 0.1,0.1
          pos_hint: {"x":0.9, "y":0.0}
          on_press:
              root.goright()
          on_release:
              root.stopright()
      Button:
          text: "&lt;"
          size_hint: 0.1,0.1
          pos_hint: {"x": 0.0, "y": 0.0}
          on_press:
              root.posx = root.posx-1
  
      Image:
          id: char
          source: "images/idle1.png"
          size: self.size
          pos: root.posx,root.posy
  </code></pre>
  
  <p>Thank you for your time and help.
  GryTrean</p>
  
  <p>//I changed "i" to "self.i" and it doesn't fix the problem.</p>