Kivy Python中图片无法重新加载的问题求助
Kivy Python中图片无法重新加载的问题求助
我刚接触Kivy,现在想实现一个功能:每秒随机生成1-3的整数,然后根据整数切换对应的图片。我用Clock每秒检查一次,打印出来看图片路径确实在变,但界面上始终是白屏(手动设置图片的时候是能正常显示的)。有没有大佬能帮忙看看问题出在哪,顺便给我讲讲原因呀?谢谢啦!
我的代码如下:
main.py
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()
servot.kv
#: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
问题分析与解决方案
我帮你找出几个关键问题,改完就能正常运行啦:
run_face方法参数错误
作为类的成员方法,run_face必须把self作为第一个参数,而且你这个方法不需要传入img_name,直接返回对应图片路径就行。修改后:def run_face(self): num = rand_num() if num == 1: return 'smile1.png' elif num == 2: return 'smile2.png' elif num == 3: return 'smile3.png'错误创建新控件实例
在swap_face里你写了self.image = FaceImage().ids.face,这相当于每次都新建一个FaceImage对象,拿的是这个新对象里的Image控件——和界面上显示的完全不是同一个!正确做法是直接获取当前实例的控件:def swap_face(self, dt): self.image = self.ids.face # 直接用当前显示的控件实例 self.image.source = self.run_face() print(self.image.source) self.image.reload()定时器挂在了错误的实例上
在ServotApp的__init__里你创建了一个FaceImage实例并启动定时器,但build方法又新建了另一个实例返回给界面,导致定时器控制的是一个没显示的对象。修改App类:class ServotApp(App): def build(self): face_img = FaceImage() face_img.img_timer() # 给要显示的实例启动定时器 return face_img
修正后的完整代码
main.py
import random from kivy.app import App from kivy.uix.boxlayout import BoxLayout 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: return 'smile1.png' elif num == 2: return 'smile2.png' elif num == 3: return 'smile3.png' def swap_face(self, dt): self.image = self.ids.face self.image.source = self.run_face() print(self.image.source) self.image.reload() class ServotApp(App): def build(self): face_img = FaceImage() face_img.img_timer() return face_img if __name__ == "__main__": ServotApp().run()
servot.kv保持不变即可。
这样修改后,界面就能正常每秒切换图片啦~核心问题就是你操作的控件和界面显示的不是同一个实例,再加上方法参数的小疏漏,调整后就没问题了。
内容来源于stack exchange
相关产品推荐
相关产品推荐

