file_picker
系统文件选择器与 AppUI FileImporter。
系统文件选择器:从「文件」App 或文档提供方导入文件,回调返回可访问路径列表。
边界:无独立import file_pickerPython 模块;通过 AppUI 的FileImporter唤起UIDocumentPicker。默认copy=True会把文件复制进 App 沙盒再返回路径。相册图片请用 photos 的PhotoPicker,不是本组件。
#模块概览
| 项 | 说明 |
|---|---|
| 导入 | import appui |
| 适合做什么 | 导入 PDF/CSV/文本、选取用户文档、批量导入附件 |
| 调用时机 | 用户点击 FileImporter 按钮;在 on_picked 回调里读文件 |
| 推荐顺序 | 点选 → on_picked(paths) → 判空 → 后台或按钮里读取 |
| 取消行为 | 用户取消通常不触发回调,或收到空列表 |
#快速开始
下面脚本展示最小文件导入页:选中文本/PDF/CSV 后列出路径。
已复制
import appui
state = appui.State(files=[])
def on_picked(paths):
state.files = paths or []
def body():
return appui.Form([
appui.FileImporter(
allowed_types=["text", "pdf", "csv"],
allows_multiple=True,
on_picked=on_picked,
label=appui.Label("选择文件", system_image="doc.badge.plus"),
),
appui.Text("已选: " + (" | ".join(state.files) if state.files else "无")),
])
appui.run(body, state=state)
#AppUI 示例
在回调里保存路径;读取文件内容放在后续按钮动作,避免在 body() 里同步读大文件。
已复制
import appui
import os
state = appui.State(
files=[],
preview="尚未选择文件",
status="点击导入按钮开始",
)
def on_files(paths):
paths = paths or []
state.files = paths
if not paths:
state.batch_update(
preview="—",
status="未选择任何文件",
)
return
name = os.path.basename(paths[0])
size = "—"
try:
size = f"{os.path.getsize(paths[0]):,} 字节"
except OSError:
pass
state.batch_update(
preview=f"{name} · {size}",
status=f"已导入 {len(paths)} 个文件",
)
def body():
rows = [
appui.Text(path).font("caption").line_limit(2)
for path in state.files
]
return appui.NavigationStack(
appui.Form([
appui.Section("导入", [
appui.FileImporter(
allowed_types=["text", "pdf", "csv", "public.data"],
allows_multiple=True,
copy=True,
on_picked=on_files,
label=appui.Label("从文件 App 导入", system_image="folder"),
),
appui.Text(state.status).foreground_color("secondaryLabel"),
]),
appui.Section("预览", [
appui.LabeledContent("首个文件", value=state.preview),
]),
appui.Section(
"路径列表",
rows or [
appui.ContentUnavailableView(
"暂无文件",
system_image="doc",
description="从系统文件选择器导入",
)
],
),
]).navigation_title("文件选择")
)
appui.run(body, state=state)
#API 参考
#速查
| 参数 | 作用 |
|---|---|
allowed_types | 限制可选类型(扩展名、MIME、UTType 名) |
allows_multiple | 是否多选 |
copy | 是否复制到沙盒(默认 True) |
on_picked | 回调 (paths: list[str]) |
label | 自定义按钮外观 |
#FileImporter {#file-importer}
FileImporter(allowed_types=None, allows_multiple=False, copy=True, on_picked=None, label=None)
已复制
def on_files_picked(paths):
print(paths)
appui.FileImporter(
allowed_types=["pdf", "csv", "text", "image/png"],
allows_multiple=False,
copy=True,
on_picked=on_files_picked,
label=appui.Button("导入"),
)
#allowed_types 常用值
| 值 | 含义 |
|---|---|
text / plain | 纯文本 |
pdf | |
csv | CSV |
image / jpeg / png | 图片 |
public.data / item | 较宽的文件类型 |
未识别类型时回退为系统通用 item。
#读取已选文件
已复制
def on_picked(paths):
if not paths:
return
with open(paths[0], "r", encoding="utf-8", errors="ignore") as f:
text = f.read(4000)
大文件请在按钮回调或后台任务读取,不要阻塞 body()。
#与 PhotoPicker 的区别
| 组件 | 来源 | 回调 |
|---|---|---|
PhotoPicker | 照片库 | 媒体文件路径列表 |
FileImporter | 文件 App / iCloud / 第三方提供方 | 任意允许类型路径列表 |
#常见错误
| 错误写法 | 后果 | 修正 |
|---|---|---|
在 body() 里 open(path) | 每次刷新重复读盘 | 放进 on_picked 或按钮回调 |
| 不处理空列表 | 取消后逻辑异常 | paths = paths or [] |
copy=False 读外部卷 | 路径可能很快失效 | 保持 copy=True(默认) |
选相册图片用 FileImporter | 体验差、类型受限 | 用 PhotoPicker |
#相关文档
| 文档 | 用途 |
|---|---|
| photos | 相册选图 / 拍照 |
| PDF 生成与预览 | |
| AppUI 媒体参考 | FileImporter 完整签名 |
| AppUI 媒体指南 | 更多媒体集成模式 |
#预期效果
运行示例后,界面应出现文档描述的目标结果;若与预期不符,先看「失败路径」并按返回值或日志排查。