KivyMD应用重跑后如何保存并加载已输入的列表数据
购物清单持久化实现方案
因为你后续要把项目打包成分发安装包,不能直接把数据存在项目源码目录下——打包后这类目录通常是只读权限,而且程序启动时也无法定位到可写的项目路径,直接写本地文件会出现退出后数据丢失、甚至直接报权限错误的问题。
正确的做法是用Kivy内置的用户专属可写目录user_data_dir存储序列化后的列表数据,配合应用生命周期钩子自动完成保存和加载,全流程不需要手动触发。
具体实现
- 不需要安装额外第三方库,用Python自带的
json序列化列表、os处理文件路径即可。 - 在应用启动阶段读取本地保存的列表数据,同步渲染到界面上。
- 在应用退出阶段自动把当前最新的列表内容写入存储文件。
代码修改点
首先在文件顶部的导入区域新增两个标准库:
import json import os
替换你当前空的on_start方法,实现启动自动加载逻辑:
def on_start(self): # 把数据文件存在应用专属可写目录,打包后全平台权限合法 self.save_file_path = os.path.join(self.user_data_dir, "shopping_list.json") global list_items # 如果历史保存文件存在,读取内容 if os.path.exists(self.save_file_path): with open(self.save_file_path, "r", encoding="utf-8") as f: list_items = json.load(f) # 把读取到的历史条目渲染到列表容器里 for item_text in list_items: self.root.ids.ms.ids.list.add_widget(OneLineAvatarIconListItem(text=item_text))
新增on_stop方法,实现退出自动保存:
def on_stop(self): # 应用完全退出前触发,把当前列表内容写入文件 global list_items with open(self.save_file_path, "w", encoding="utf-8") as f: json.dump(list_items, f, ensure_ascii=False)
补充说明
- 所有你现有的增删列表的逻辑不需要额外改动,只要保持操作时同步更新全局
list_items变量,退出时就会把最新内容持久化,不需要每次操作都手动写文件。 - 不要把存储路径换成和
main.kv同目录的相对路径,打包成exe/apk后这类相对路径会指向临时解压的只读目录,写入的内容下次启动一定会丢失。 - 你当前的
remove_one_item方法用文本匹配定位列表项的逻辑有小隐患:如果添加了两个完全一样的购物项,会误删第一个匹配的条目,这个可以后续优化,但不影响持久化功能本身。
内容的提问来源于stack exchange,提问作者Zeej
相关产品推荐
相关产品推荐

