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

Kivy拖动滑动条保存图片后界面未重绘问题求助

问题排查与修复方案

核心问题原因

  • Kivy的Image组件默认会缓存已加载的图片资源,你虽然更新了本地TestImage.png文件的内容,但组件不会主动检测文件变更,仍然显示缓存的旧图片。
  • 每次滑动条回调时都会往根布局画布中新增一个ImageKv实例,旧的图片组件没有被清理,始终叠在层级上方遮挡新内容。
  • 画布中添加的Color指令是全局生效的,会对后续所有绘图元素造成不必要的色彩偏移,此处加载图片完全不需要额外加颜色指令。

修复步骤

  1. 把ImageKv实例作为App的属性保存,仅在第一次点击OK时创建,后续不再重复生成
  2. 每次更新图片文件后,调用ImageKv实例的reload()方法刷新缓存,触发重绘
  3. 移除view_image方法中多余的Color指令

修复后完整代码

from kivy.core.window import Window
from kivy.app import App
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.button import Button
from kivy.uix.image import Image as ImageKv
from kivy.uix.slider import Slider

from PIL import  Image, ImageDraw


class View():
    # 新增参数接收已存在的ImageKv实例,没有的话就创建
    def view_image(self, size, pos, canvas, filename, img_widget=None):
        if not img_widget:
            rect = ImageKv(source=filename,pos=pos, size=size )
            with canvas:
                canvas.add(rect)
            return rect
        else:
            img_widget.source = filename
            img_widget.reload()
            return img_widget

class MainApp(App):

    def OnAzmSliderValueChange(self, instance,value):
        if self.image != None:
            self.photo.polygon(self.polygon, fill = 'green')
            self.image.save(self.img_name)
            # 传入已有的img_widget更新内容
            self.img_widget = self.view.view_image(self.size, self.pos, self.root.canvas, self.img_name, self.img_widget)
        return

    def build(self):
        self.image = None
        self.img_name = "TestImage.png"
        self.img_widget = None # 保存ImageKv实例

        self.img_h = 2000
        self.img_w = 3000

        (dim_x, dim_y) = Window.size

        self.pos = (0, int(dim_y*0.1))
        self.size = (int(dim_x * 0.9),int(dim_y*0.7))

        x_center = dim_x/2
        y_center = dim_y/2

        self.polygon = [x_center - dim_x/2, y_center - dim_y/2,
                        x_center - dim_x/2, y_center + dim_y/2,
                        x_center + dim_x/2, y_center + dim_y/2,
                        x_center + dim_x/2, y_center - dim_y/2]

        root = RelativeLayout(size =(dim_x, dim_y))

        slider_hor = Slider(min= 0, max=360, step = 10, value = 0, orientation='horizontal', size_hint = (0.9, 0.1), pos = (0,int(dim_y*4/5.0)))
        root.add_widget(slider_hor)
        slider_hor.bind(value=self.OnAzmSliderValueChange)

        bt_ready = Button(text = 'OK', pos = (0, 0), size_hint = (1,0.1), on_press = self.cmd_ok)
        root.add_widget(bt_ready)

        self.root = root
        return root


    def cmd_ok(self, instance):
        self.image = Image.new("RGB", (self.img_w, self.img_h), 'yellow')
        self.photo = ImageDraw.Draw(self.image)

        self.photo.polygon(self.polygon, fill = 'red')
        self.image.save(self.img_name)

        self.view = View()
        # 第一次创建保存实例
        self.img_widget = self.view.view_image(self.size, self.pos, self.root.canvas, self.img_name)
        return

if __name__ == '__main__':
    MainApp().run()

内容的提问来源于stack exchange,提问作者jasan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 03:54:02