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

如何在KivyMD中保存用户输入的图像文件,实现重启应用后仍可访问

解决方案

实现思路

我们用Kivy自带的JsonStore做持久化存储,同时把用户上传的图片复制到应用专属数据目录,避免原文件移动/删除后无法访问,整体逻辑如下:

  • 应用启动时读取本地存储的图片路径、日期信息,自动回填到界面
  • 用户选择图片后,先将图片复制到应用专属的用户数据目录,再更新界面和存储记录
  • 应用退出时自动保存当前所有输入内容

完整修改后的代码

from kivy.lang import Builder
from kivymd.app import MDApp
from kivy.core.window import Window
from plyer import filechooser
from kivy.storage.jsonstore import JsonStore
import os
import shutil

Window.size = (300, 530)

KV = """
MDBoxLayout:
    orientation: 'vertical'

    MDToolbar:
        id: progress_toolbar
        title: 'Progress'

    ScrollView:
        MDGridLayout:
            cols: 2
            adaptive_height: True
            spacing: (10, 15)
            padding: [25, 25]

            MDLabel:
                halign: 'center'
                text: 'Before'

            MDLabel:
                halign: 'center'
                text: 'Now'

            MDCard:
                ripple_behavior: True
                orientation: 'vertical'
                size_hint_y: None
                size: 120, 220
                elevation: 15
                radius: 8
                MDIconButton:
                    icon: "camera-outline"
                    user_font_size: "24sp"
                    pos_hint: {"center_x": .5, "center_y": .5}
                    on_release: app.file_chooser1()
                Image:
                    id: img1
                    allow_stretch: True
                    keep_ratio: False

            MDCard:
                ripple_behavior: True
                orientation: 'vertical'
                size_hint_y: None
                size: 120, 220
                elevation: 15
                radius: 8
                MDIconButton:
                    icon: "camera-outline"
                    user_font_size: "24sp"
                    pos_hint: {"center_x": .5, "center_y": .5}
                    on_release: app.file_chooser2()
                Image:
                    id: img2
                    allow_stretch: True
                    keep_ratio: False


            MDTextField:
                id: date1
                hint_text: 'Date'
                width: 100

            MDTextField:
                id: date2
                hint_text: 'Date'
                width: 100

"""


class Example(MDApp):
    def build(self):
        # 初始化存储,配置文件保存在应用专属数据目录
        self.store = JsonStore(os.path.join(self.user_data_dir, 'app_data.json'))
        # 创建保存图片的目录
        self.img_dir = os.path.join(self.user_data_dir, 'uploaded_imgs')
        os.makedirs(self.img_dir, exist_ok=True)
        return Builder.load_string(KV)

    def on_start(self):
        # 启动时读取存储的内容回填到界面
        if self.store.exists('data'):
            data = self.store.get('data')
            self.root.ids.img1.source = data.get('img1_path', '')
            self.root.ids.img2.source = data.get('img2_path', '')
            self.root.ids.date1.text = data.get('date1', '')
            self.root.ids.date2.text = data.get('date2', '')

    def on_stop(self):
        # 退出时保存当前内容
        self.store.put('data',
                       img1_path=self.root.ids.img1.source,
                       img2_path=self.root.ids.img2.source,
                       date1=self.root.ids.date1.text,
                       date2=self.root.ids.date2.text)

    def file_chooser1(self):
        filechooser.open_file(on_selection=self.selected1, filters=['*.png', '*.jpg', '*.jpeg'])

    def file_chooser2(self):
        filechooser.open_file(on_selection=self.selected2, filters=['*.png', '*.jpg', '*.jpeg'])

    def selected1(self, selection1):
        if not selection1:
            return
        # 复制图片到应用专属目录
        src_path = selection1[0]
        file_name = os.path.basename(src_path)
        dst_path = os.path.join(self.img_dir, f'img1_{file_name}')
        shutil.copy2(src_path, dst_path)
        # 更新界面
        self.root.ids.img1.source = dst_path

    def selected2(self, selection2):
        if not selection2:
            return
        src_path = selection2[0]
        file_name = os.path.basename(src_path)
        dst_path = os.path.join(self.img_dir, f'img2_{file_name}')
        shutil.copy2(src_path, dst_path)
        self.root.ids.img2.source = dst_path


Example().run()

注意事项

  • 所有数据默认保存在系统分配给应用的专属目录,无需额外申请存储权限,打包为移动端APP时也可正常运行
  • 每次用户上传新图片会覆盖之前的旧图片,如果你需要保留历史记录,只需修改存储结构,添加分组标识即可
  • 如果需要限制图片大小,可在复制文件前加压缩逻辑,减少存储空间占用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 12:36:05