So I'm very new to Kivy, and the point here is to have a random integer cycle through 3 random integers and change images corresponding to the integers, with a clock checking this every second. It does show its being changed, even the image source seems to be changing but I'm not seeing any update, just a white screen (And yes, the images did work before when set manually, without this code). Some good help and explanation would go a long way, thanks!
import random
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.image import Image
from kivy.clock import Clock
def rand_num():
num = random.randint(1,3)
return num
class FaceImage(BoxLayout):
def img_timer(self):
Clock.schedule_interval(self.swap_face, 1)
def run_face(img_name):
num = rand_num()
if num == 1:
img_name = 'smile1.png'
elif num == 2:
img_name = 'smile2.png'
elif num == 3:
img_name = 'smile3.png'
return img_name
def swap_face(self, dt):
self.image = FaceImage().ids.face
self.image.source = self.run_face()
print(self.image.source)
self.image.reload()
class ServotApp(App):
def __init__(self, **kwargs):
super(ServotApp, self).__init__(**kwargs)
self.img_obj = FaceImage()
self.img_obj.img_timer()
def build(self):
face_img = FaceImage()
return face_img
if __name__ == "__main__":
ServotApp().run()
#:kivy 2.3.1
<FaceImage>:
orientation: 'vertical'
canvas:
Color:
rgba: 1, 0.93, 0.75, 1
Rectangle:
pos: self.pos
size: self.size
Image:
id: face
size: self.size
A couple problems with your code. First, whenever you use FaceImage()
you are creating a new instance of FaceImage
. So your __init__()
code is creating a new instance of FaceImage
(which is not the instance that you are expecting to see in your App
window) and calling img_timer()
on that instance. The result is that you are swapping sources in an Image
that is not part of your display.
Similarly, your swap_face()
method is creating yet another instance of FaceImage
which is also not in your App
display.
To fix these problems, you can eliminate your __init__()
method completely. Then modify your build()
method to call your img_timer()
, and modify swap_face()
method to use the actual instance of FaceImage
that is in your App
display. Your run_face()
method should have self
as its only arg. With those corrections, you also do not need a call to reload()
the Image
. Here is a modified version of your code with those corrections:
import random
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.image import Image
from kivy.clock import Clock
def rand_num():
num = random.randint(1, 3)
return num
class FaceImage(BoxLayout):
def img_timer(self):
Clock.schedule_interval(self.swap_face, 1)
def run_face(self):
num = rand_num()
if num == 1:
img_name = 'smile1.png'
elif num == 2:
img_name = 'smile2.png'
elif num == 3:
img_name = 'smile3.png'
return img_name
def swap_face(self, dt):
self.image = self.ids.face
self.image.source = self.run_face()
print(self.image.source)
class ServotApp(App):
def build(self):
face_img = FaceImage()
face_img.img_timer()
return face_img
if __name__ == "__main__":
ServotApp().run()