You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 11:19:30