Kivy Images Not Showing Without Added Time
Question: # Summary of this app:

  * Raspberry Pi running Raspbian Jessie and output to TV
  * Python 3.4
  * Kivy 1.9.1
  * pet information is pulled through a SOAP request
  * the information is parsed
  * a kivy window is created and the pet information is displayed for a set interval before the next pet's information is displayed

# Issue:

  * each pet has a single image (typically 20-60kB each) which many times is not being displayed
  * initially I was using asynchronous loading to pull the image and display it direct from it's web address
  * now I am downloading every image to a USB drive prior to starting the display sequence, but having the same issues
  * the pre-loaded images open fine outside of the app
  * when the images were pulled direct from the web, it took about a second for the image to display (or not display)
  * now that the images are downloaded first, the images appear almost instantly (or not appear)
  * 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)
  * I tried using and not using asynchronous loading with images stored on the USB stick without success either way
  * 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)
  * I've tried adding a delay between the downloading/saving of each image with no luck
  * the first 7 images always succeed, independent of whatever list of pets are loaded
  * after the first 7 images, it is random with the success rate dependent on the time interval between pets being displayed
  * 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

## Python

`

    
    
    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 < 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 < 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()
    

`

## Kivy Language

`

    
    
    #:kivy 1.9.1
    
    <TheBox>:
        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:
                    ..
    


Answer: Not positive on this on this correlation, but it seems to make sense. I
increased the GPU memory for the Raspberry Pi from 64 to 128MB and now the
application is able to successfully display the images with a much smaller
interval between image changes.

