title: Kivy Images Not Showing Without Added Time
body: <h1>Summary of this app:</h1>
  
  <ul>
  <li>Raspberry Pi running Raspbian Jessie and output to TV</li>
  <li>Python 3.4</li>
  <li>Kivy 1.9.1</li>
  <li>pet information is pulled through a SOAP request</li>
  <li>the information is parsed</li>
  <li>a kivy window is created and the pet information is displayed for a
  set interval before the next pet's information is displayed</li>
  </ul>
  
  <h1>Issue:</h1>
  
  <ul>
  <li>each pet has a single image (typically 20-60kB each) which many times is not being displayed</li>
  <li>initially I was using asynchronous loading to pull the image and display it direct from it's web address</li>
  <li>now I am downloading every image to a USB drive prior to starting the display sequence, but having the same issues</li>
  <li>the pre-loaded images open fine outside of the app</li>
  <li>when the images were pulled direct from the web, it took about a second for the image to display (or not display)</li>
  <li>now that the images are downloaded first, the images appear almost instantly (or not appear)</li>
  <li>the only way that I can guarantee that every image will display is to set the time interval between pets to 20 or more seconds (whether direct from the web or pulled from the USB stick)</li>
  <li>I tried using and not using asynchronous loading with images stored on the USB stick without success either way</li>
  <li>I've watched the folder on the USB stick and can see that the images load at a rate of about 1-3 images per second (total of about 110 images)</li>
  <li>I've tried adding a delay between the downloading/saving of each image with no luck</li>
  <li>the first 7 images always succeed, independent of whatever list of pets are loaded</li>
  <li>after the first 7 images, it is random with the success rate dependent on the time interval between pets being displayed</li>
  <li>I can't figure out why the added time is necessary for all images to show when the images are rather small and the ones that do show appear almost instantly</li>
  </ul>
  
  <h2>Python</h2>
  
  <p><code></p>
  
  <pre><code>import kivy
  import sys
  import os
  import time
  import requests
  kivy.require('1.9.1')
  import xml.etree.ElementTree as ET
  from datetime import datetime
  from kivy.app import App
  from kivy.core.window import Window
  from kivy.uix.floatlayout import FloatLayout
  from kivy.clock import Clock
  
  # from kivy.loader import Loader
  # image = Loader.image('nophoto.png')
  # Loader.error_image = 'nophoto.png'
  
  # SET ADDRESS FOR SOAP
  from suds.client import Client
  url = 'http://qag.petpoint.com/webservices/AdoptableSearch.asmx?WSDL'
  client = Client(url)
  
  # DELETES PRELOADED IMAGES TO START WITH AN EMPTY USB FOLDER
  for ea_file in os.listdir('/media/pi/PRELOAD'):
      thedress = '/media/pi/PRELOAD' + '/' + ea_file
      os.remove(thedress)
  
  # PUSHES DYNAMIC INFO TO SCROLLER.KV
  class TheBox(FloatLayout):
      def update(self, *args):
          global date_now, which_petL, which_petR, total_count, Lname, Lsex, Lbreed, Lage, Lphoto, Rname, Rsex, Rbreed, Rage, Rphoto
          quantity = len(ans_lists[0]) - 1
  
          ans_particular = feeder()
          Lname = ans_particular[0]
          Lsex = ans_particular[1]
          Lbreed = ans_particular[2]
          Lage = ans_particular[3]
          Lphoto = ans_particular[4]
          Rname = ans_particular[5]
          Rsex = ans_particular[6]
          Rbreed = ans_particular[7]
          Rage = ans_particular[8]
          Rphoto = ans_particular[9]
  
          self.ids.Start_Time.text = '%02d  %02d    %05d' % (date_now.day, date_now.hour, total_count)
  
          if (total_count % 2) == 0: 
              if which_petL &lt; quantity:
                  which_petL += 1
              else:
                  which_petL = 0
  
              self.ids.PetL_name.text = str.upper(Lname)
              self.ids.PetL_sex.text = str(Lsex)
              self.ids.PetL_breed.text = str(Lbreed)
              self.ids.PetL_age.text = str(Lage)
              self.ids.PetL_photo.source = str(Lphoto)
  
          else:
              if which_petR &lt; quantity:
                  which_petR += 1
              else:
                  which_petR = 0
  
              self.ids.PetR_name.text = str.upper(Rname)
              self.ids.PetR_sex.text = str(Rsex)
              self.ids.PetR_breed.text = str(Rbreed)
              self.ids.PetR_age.text = str(Rage)
              self.ids.PetR_photo.source = str(Rphoto)
  
  # SOAP RESPONSE IS CONVERTED TO XML FORMAT
  def reformat_soap():    
      result = client.service.adoptableSearch('0', 'A', 'All', 'not4u')
  
      ..
  
      root = ET.fromstring(closeit)
      return root
  
  # ITERATES THE SOAP RESPONSE TO ASSIGN DATA TO LISTS
  def pull_data(ans_root):
      lpetid = []
      lname = []
      lsex = []
      lbreed = []
      lage = []
      lphoto = []
  
      for child in ans_root.iter('pet_id'):
  
          ..
  
          iphoto = child.find('pet_photo').text
  
          # WEB ADDRESSES FOR IMAGES ARE USED TO CREATE LOCAL ADDRESSES
          local_name = iphoto.replace('http://sms.petpoint.com/sms/photos/615/','/media/pi/PRELOAD/')
          ghost_pet = local_name.replace('http://sms.petpoint.com/sms3/emails/images/','/media/pi/PRELOAD/')
          lphoto.extend([ghost_pet])
  
          # IMAGES ARE DOWNLOADED FROM THE WEB AND SAVED LOCALLY
          photo_cache = open(ghost_pet, 'wb')
          photo_cache.write(requests.get(iphoto).content)
  #       time.sleep(2)
          photo_cache.close()
  
      return(lname, lsex, lbreed, lage, lphoto)
  
  # ASSEMBLES PET DATA PRIOR TO PUSH
  def feeder():
      global which_petL, which_petR, cname, csex, cbreed, cage, cphoto
      pname = cname[which_petL]
      psex = csex[which_petL]
      pbreed = cbreed[which_petL]
      page = cage[which_petL]
      pphoto = cphoto[which_petL]
      qname = cname[which_petR]
      qsex = csex[which_petR]
      qbreed = cbreed[which_petR]
      qage = cage[which_petR]
      qphoto = cphoto[which_petR]    
      return(pname, psex, pbreed, page, pphoto, qname, qsex, qbreed, qage, qphoto) 
  
  ans_root = reformat_soap()
  ans_lists = pull_data(ans_root)
  which_petR = int(len(ans_lists[0]) / 2)
  
  cname = ans_lists[0]
  csex = ans_lists[1]
  cbreed = ans_lists[2]
  cage = ans_lists[3]
  cphoto = ans_lists[4]
  
  # DEFINES THE KIVY APP, INTERVAL BETWEEN PET DISPLAYS, AND TIES TO SCROLLER.KV
  class ScrollerApp(App):
  
      def build(self):
          self.load_kv('Scroller.kv')
          x = TheBox()
          x.update()
          Clock.schedule_interval(x.update, 10)
          return(x)
  
  # KIVY WINDOW CREATION
  if __name__ == '__main__':
      ScrollerApp().run()
  </code></pre>
  
  <p></code></p>
  
  <h2>Kivy Language</h2>
  
  <p><code></p>
  
  <pre>#:kivy 1.9.1
  
  &lt;TheBox&gt;:
      FloatLayout:
          FloatLayout:
              size: 810, 1080
              pos_hint: {'center_x': .21}
              Image:
                  canvas.before:
                      Color:
                          rgb: (0, 0, 0)
                      Rectangle:
                          pos: self.pos
                          size: self.size
                  id: PetL_photo
                  size_hint: None, None
                  size: 790, 770
                  pos_hint: {'center_x': .5, 'center_y': .64} 
                  allow_stretch: True
                  keep_ratio: True
                  source:
              Label:
                  ..
              Label:
                  ..
              Label:
                  ..
              Label:
                  ..
          FloatLayout:
              ..
          FloatLayout:
              size: 810, 1080
              pos_hint: {'center_x': .79}
              Image:
                  canvas.before:
                      Color:
                          rgb: (0, 0, 0)
                      Rectangle:
                          pos: self.pos
                          size: self.size
                  id: PetR_photo
                  size_hint: None, None
                  size: 790, 770
                  pos_hint: {'center_x': .5, 'center_y': .64} 
                  allow_stretch: True
                  keep_ratio: True
                  source:
              Label:
                  ..
              Label:
                  ..
              Label:
                  ..
              Label:
                  ..
  </code></pre>
  
  <p>