ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Flet FilePickerUploadEvent 实战指南:用 on_upload 实现文件上传进度监控

Flet FilePickerUploadEvent 实战指南:用 on_upload 实现文件上传进度监控 前端跨平台桌面应用移动开发【免费下载链接】fletBuild realtime web, mobile and desktop apps in Python only. No frontend experience required.项目地址https://gitcode.com/gh_mirrors/fl/flet点击查看免费下载FilePickerUploadEvent是 Flet 中由FilePicker.upload()触发上传时携带进度与错误信息的核心事件对象它通过FilePicker.on_upload事件处理器将上传的实时进度0.0 ~ 1.0回传给 Python 侧。读完本文你将掌握FilePickerUploadEvent三个字段的语义、上传进度事件的触发时机与频率并能在真实应用中用它驱动进度条、处理上传失败与多文件上传场景。一、FilePickerUploadEvent 是什么FilePickerUploadEvent定义于 sdk/python/packages/flet/src/flet/controls/services/file_picker.py是一个基于Event[FilePicker]的 dataclass用于承载单次文件上传过程中的状态快照。它是 Flet 文档站中FilePickerUploadEvent类型页即 website/docs/types/filepickeruploadevent.md所渲染 API 的权威来源——该类型页通过ClassAll nameflet.FilePickerUploadEvent /组件直接内联渲染源码中的 docstring因此本文以源码实现为准展开讲解。dataclass class FilePickerUploadEvent(Event[FilePicker]): file_name: str progress: Optional[float] None error: Optional[str] None该事件对象本身不包含文件内容它只是一个状态信号告诉你的 Python 代码哪个文件正在上传、上传到多少了、以及是否出错。二、三个字段的完整语义1.file_name: str必填被上传文件的名称basename。在多文件上传场景中file_name是区分不同上传流的唯一稳定标识通常直接用作进度组件的键keyprog_bars: dict[str, ft.ProgressRing] {} def on_upload_progress(e: ft.FilePickerUploadEvent): prog_bars[e.file_name].value e.progress由于upload()是逐文件顺序执行的见下文 Dart 端实现同一个file_name的事件会在时间上连续出现可以放心用它作为字典键。2.progress: Optional[float]上传进度取值范围0.0到1.0None表示当前无进度信息。其语义在on_upload的 docstring 中有明确规定每个文件至少触发两次上传开始前触发一次0.0上传完成时触发一次1.0超过 1 MB 的大文件除首尾外每增加 10% 增量额外触发一次事件如0.1、0.2……0.9。这一触发节奏在 Flutter 客户端源码 packages/flet/lib/src/services/file_picker.dart 的uploadFile()方法中有精确对应实现上传开始时先发送0// send 0%随后在流式读取文件块时累计bytesSent以progress bytesSent / file.size计算进度并仅在progress lastSent即每跨越 0.1 的整数倍时发送一次progress ! 1.0的判断保证最终1.0由成功回调统一发出。因此前端驱动的ProgressRing或ProgressBar可以直接把e.progress赋值给value属性无需额外换算。3.error: Optional[str]上传失败时的错误信息成功时为None。从 Dart 端实现看错误来源有两类客户端异常如无法读取文件流Cannot read file from null stream、网络异常此时sendProgress(file.name, null, e.toString())会把异常字符串传给error服务端响应异常上传请求返回的状态码不在200 ~ 204范围内时错误信息为Upload endpoint returned code {status}: {body}。Python 侧判错的写法def on_upload_progress(e: ft.FilePickerUploadEvent): if e.error: print(f上传失败: {e.file_name} - {e.error}) return prog_bars[e.file_name].value e.progress注意error非空时progress通常为None两者是互斥状态处理时建议先判error。三、上传流程与事件如何被触发FilePickerUploadEvent只能通过FilePicker.on_upload事件处理器接收触发链路如下await file_picker.upload(files[...]) # Python 侧发起 │ ▼ 客户端按顺序逐文件上传Flutter: uploadFiles / uploadFile │ ▼ 每到达 0%、10% 增量、100% 或出错 ▼ 触发 upload 事件构造 FilePickerUploadEvent(file_name, progress, error) │ ▼ Python 侧 on_upload 处理器被调用关键点upload()是异步方法但上传本身由客户端逐个文件串行执行Python 侧通过on_upload被动接收进度无需轮询。FilePickerUploadEvent的完整使用流程包含三个环节选文件调用FilePicker.pick_files()或使用PickFiles客户端动作构造上传描述为每个选中文件创建一个FilePickerUploadFile指定upload_url与方法发起上传调用FilePicker.upload(files)同时在FilePicker构造时挂上on_upload处理器。四、可运行的完整示例多文件上传 实时进度条仓库自带的 sdk/python/examples/services/file_picker/pick_and_upload/main.py 是官方示例Web 模式完整展示了如何用FilePickerUploadEvent驱动每个文件的ProgressRingimport flet as ft def main(page: ft.Page): prog_bars: dict[str, ft.ProgressRing] {} def on_upload_progress(e: ft.FilePickerUploadEvent): prog_bars[e.file_name].value e.progress async def handle_files_pick(e: ft.Event[ft.Button]): state.file_picker ft.FilePicker(on_uploadon_upload_progress) files await state.file_picker.pick_files(allow_multipleTrue) state.picked_files files upload_button.disabled len(files) 0 prog_bars.clear() upload_progress.controls.clear() for f in files: prog ft.ProgressRing(value0, bgcolor#eeeeee, width20, height20) prog_bars[f.name] prog upload_progress.controls.append(ft.Row([prog, ft.Text(f.name)])) async def handle_file_upload(e: ft.Event[ft.Button]): upload_button.disabled True await state.file_picker.upload( files[ ft.FilePickerUploadFile( namefile.name, upload_urlpage.get_upload_url(fdir/{file.name}, 60), ) for file in state.picked_files ] ) page.add( ft.SafeArea( contentft.Column( controls[ ft.Button(contentSelect files..., iconft.Icons.FOLDER_OPEN, on_clickhandle_files_pick), upload_progress : ft.Column(), upload_button : ft.Button(contentUpload, iconft.Icons.UPLOAD, on_clickhandle_file_upload, disabledTrue), ], ), ) ) if __name__ __main__: ft.run(main, upload_direxamples)要点拆解进度条以file_name为键每次 pick 后清空并重建prog_bars字典避免旧文件残留upload_url由page.get_upload_url()生成这是 Flet 内部上传存储的预签名 URL第二个参数60是 URL 有效期秒ft.run(main, upload_direxamples)upload_dir指定服务端保存上传文件的目录未设置时上传目标不会落盘该示例的元数据sdk/python/examples/services/file_picker/pick_and_upload/pyproject.toml声明了features [file upload, upload progress]、platforms [web]即该示例定位为 Web 模式的文件上传与进度演示。另一个官方示例 sdk/python/examples/services/file_picker/pick_files_action/main.py 展示了PickFiles客户端动作版本选文件由按钮的actionft.PickFiles(file_picker, allow_multipleTrue)在用户手势内触发这在 iOS Web 应用中才能弹出文件选择器结果通过on_result到达之后upload()与进度处理方式完全相同。五、upload() 与 FilePickerUploadFile 的配合细节FilePicker.upload()的签名源码见 file_picker.pyasync def upload(self, files: list[FilePickerUploadFile]):每个FilePickerUploadFile包含四个字段字段默认值说明upload_url必填上传目标 URL可为绝对 URL 或page.get_upload_url()返回的相对 URLmethodPUT上传使用的 HTTP 方法通常为PUT或POSTidNonepick_files()返回的文件标识同时提供id与name时优先按id匹配nameNone文件名作为id缺失或匹配失败时的回退匹配键Dart 端 uploadFiles() 的匹配逻辑与此一致先按id在本次选择中定位文件找不到再按name回退定位成功后逐文件执行上传成功上传的文件会从客户端选择列表中移除因此重复上传同一批文件前需重新 pick。若文件匹配失败客户端仅输出调试日志不会触发上传事件。另外两点与上传存储直接相关多用户隔离page.get_upload_url(f/{username}/pictures/{f.name}, 600)中带路径前缀的 URL 会在upload_dir下自动创建对应目录详见 website/docs/services/filepicker.md 的说明换用任意存储upload_url不限于 Flet 内部存储任何返回 2xx 的预签名上传端点如 S3 兼容对象存储均可作为目标method按需设为PUT或POST。六、错误处理与调试建议综合 Dart 端实现与事件字段语义实际开发中建议先判 error 再读 progresserror非空即视为本次上传失败此时progress无意义关注 1.0 与 0.0 两端的确定性无论文件多小0.0与1.0必然各触发一次可用e.progress 1.0作为该文件上传完成的收尾信号例如禁用该文件对应的进度行、显示完成标记大文件才有多段进度小于 1 MB 的文件只会收到0.0和1.0两个事件进度条动画应能容忍从 0 直接跳到 1上传前先 pickupload()依赖 FilePicker 内部的选择状态官方文档明确要求先调用pick_files()确保选择非空否则文件定位会失败服务端 2xx 判定客户端只把200~204视为成功其他状态码会以Upload endpoint returned code ...形式进入error字段排查时可据此区分网络层错误与业务层错误。通过FilePickerUploadEventFlet 把原本需要自行封装的上传进度上报逻辑收敛为一个事件对象 一个回调配合ProgressRing/ProgressBar的value绑定即可在几行代码内实现完整的文件上传进度界面。赞分享前端跨平台桌面应用移动开发【免费下载链接】fletBuild realtime web, mobile and desktop apps in Python only. No frontend experience required.项目地址https://gitcode.com/gh_mirrors/fl/flet点击查看免费下载相关推荐RiverTrail Mandelbrot分形示例深度解析并行计算的魅力RiverTrail Mandelbrot分形示例深度解析并行计算的魅力 RiverTrail是一个专注于JavaScript数据并行处理的API它通过简洁开发工具FLAN-T5-XXL分词器深潜SentencePiece、512上下文与100个特殊Token揭秘FLAN T5 XXL分词器深潜SentencePiece、512上下文与100个特殊Token揭秘 FLAN T5 XXL 是谷歌开源的指令微调文本生成大模claude-obsidian如何防提示注入把网页内容当不可信数据的设计claude obsidian如何防提示注入把网页内容当不可信数据的设计 claude obsidian 是一个开源的 AI 第二大脑把任何来源交给 ClaAI 技能知识库知识管理RAG人工智能创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表