前端跨平台桌面应用移动开发【免费下载链接】fletBuild realtime web, mobile and desktop apps in Python only. No frontend experience required.项目地址https://gitcode.com/gh_mirrors/fl/flet点击查看免费下载导读FilePickerResultEvent是 Flet 文件选择服务中负责承载选择结果的核心事件类型当用户通过PickFiles客户端动作完成文件选择或取消选择后Flet 会构造该事件对象并传递给FilePicker.on_result回调。本文以 Flet SDK 的源码实现为据完整讲解该事件类的字段语义、触发时机、与pick_files()返回值的区别并结合仓库示例给出可直接运行的实战代码与 Web 端最佳实践。什么是 FilePickerResultEvent类定义与继承关系在 Flet 中FilePickerResultEvent定义于 sdk/python/packages/flet/src/flet/controls/services/file_picker.py第 146-159 行是一个继承自Event[FilePicker]的 dataclassdataclass class FilePickerResultEvent(Event[FilePicker]): Event emitted when files are selected through a :class:~flet.PickFiles action. Not emitted by :meth:flet.FilePicker.pick_files, which returns the selected files directly. files: list[FilePickerFile] The selected files, or an empty list if the user cancelled. 它继承的基类Event定义于 sdk/python/packages/flet/src/flet/controls/control_event.py第 108-136 行是 Flet 所有控件事件回调的统一负载类型本身携带三个通用字段name事件名称字符串data可选的原始事件数据control触发该事件的控件实例即FilePicker本身。基于Event基类FilePickerResultEvent通过control字段即可访问其所属的FilePicker并通过page属性获得持有该控件的Page对象。在此基础上FilePickerResultEvent增加了一个独有的业务字段files这也是它在实际开发中唯一需要直接操作的属性。官方文档中的呈现方式仓库中对应的类型文档页本身仅是一个占位文件它通过引入ClassAll组件实现于 website/src/components/crocodocs/ClassAll.js把该类的完整 API 文档docstring、成员签名、字段说明从 SDK 源码动态渲染到文档站中。因此本文所述的字段与行为细节其权威来源正是上面列出的 SDK 源码。核心字段filesfiles的类型为list[FilePickerFile]是本次选择得到的文件元数据列表其语义包含两个关键点选择成功时列表包含用户选中的全部文件每个元素都是一个FilePickerFile对象用户取消时列表为空[]而不是None。与旧版 Flet如 2022 年发布文件选择功能时的行为见博客文章相比当前版本的语义已经明确收敛FilePickerResultEvent不再承载path等字段save_file()与get_directory_path()的路径结果改为由方法返回值直接提供事件只负责“Pick files”场景的选择结果。FilePickerFile 的字段构成files列表中的每个元素是FilePickerFile定义于同一文件的第 98-143 行其字段如下字段类型说明idintFlet 分配的选择级文件标识仅在当前选择会话内稳定上传匹配时优先使用namestr文件名basename不含目录路径sizeint文件大小字节pathstr \| None文件的绝对路径Web 模式恒为None原生平台上若系统选择器不暴露路径也可能为Nonebytesbytes \| None文件内容仅当pick_files(with_dataTrue)时才有值否则为None空列表的判定技巧由于取消选择时files是空列表而非None判断用户是否取消可以简单地使用真假值判定或者显式检查len(e.files) 0def handle_result(e: ft.FilePickerResultEvent): if not e.files: print(Selection cancelled) return for f in e.files: print(fPicked: {f.name} ({f.size} bytes))触发时机on_result 回调注册方式FilePickerResultEvent通过FilePicker.on_result事件处理器被回调。在创建FilePicker实例时传入即可import flet as ft def handle_result(e: ft.FilePickerResultEvent): # e.files 即为本次选择的文件列表 ... file_picker ft.FilePicker(on_resulthandle_result) page.services.append(file_picker)什么场景会触发它源码 docstring 明确强调该事件仅由PickFiles客户端动作触发pick_files()方法不会触发它——因为pick_files()是异步方法选择结果直接作为返回值返回给调用方见 file_picker.py 第 333-392 行方法返回list[FilePickerFile]。PickFiles是一个ClientAction同文件第 401-485 行它把文件选择对话框的打开动作绑定在控件自身由客户端在用户的原始手势click / key press内完成这正是浏览器唯一允许打开文件选择器的时机。选择结果无法同步返回给 Python 调用方于是通过on_result事件送达——也就是FilePickerResultEvent的核心使用场景。源码对两种方式的结果获取路径做了清晰的对比获取方式结果返回途径适用场景await file_picker.pick_files(...)方法返回值list[FilePickerFile]桌面端、按钮on_click中直接调用ft.PickFiles(file_picker, ...)动作FilePicker.on_result回调即FilePickerResultEventWeb 端尤其是 iOS Safari必须保持浏览器手势Web 端必须使用动作的原因在 Web 应用中浏览器只会在处理点击或按键事件时打开文件选择器。如果在on_click回调里调用pick_files()点击事件已经先传到 Python 代码、指令再传回浏览器此时“用户手势”的权限已失效Safari 会静默拒绝Chrome 和 Firefox 则允许。这导致同一应用往往在除 iPhone/iPad 外的所有平台都能工作。因此官方文档filepicker.md建议将PickFiles动作挂到控件上让对话框在原始手势内打开并在on_result中处理选择结果。实战基于 on_result 的多文件选择与上传下面的示例取自仓库示例 pick_files_action/main.py完整演示了FilePickerResultEvent的典型用法——通过PickFiles动作触发选择在on_result中读取e.files展示文件列表最后把文件交给upload()上传import flet as ft from dataclasses import dataclass, field dataclass class State: picked_files: list[ft.FilePickerFile] field(default_factorylist) state State() def main(page: ft.Page): prog_bars: dict[str, ft.ProgressRing] {} def handle_upload_progress(e: ft.FilePickerUploadEvent): prog_bars[e.file_name].value e.progress def handle_result(e: ft.FilePickerResultEvent): # PickFiles 动作在 Python 看到点击之前就打开了对话框 # 所以选择结果在这里到达而不是返回给调用方。 state.picked_files e.files prog_bars.clear() upload_progress.controls.clear() for f in e.files: prog ft.ProgressRing(value0, bgcolor#eeeeee, width20, height20) prog_bars[f.name] prog upload_progress.controls.append( ft.Row([prog, ft.Text(f{f.name} ({f.size} bytes))]) ) upload_button.disabled len(e.files) 0 async def handle_file_upload(e: ft.Event[ft.Button]): upload_button.disabled True # 被选中的文件仍然关联在 FilePicker 上upload() 直接使用它们。 await file_picker.upload( files[ ft.FilePickerUploadFile( namefile.name, upload_urlpage.get_upload_url(fdir/{file.name}, 60), ) for file in state.picked_files ] ) file_picker ft.FilePicker( on_resulthandle_result, on_uploadhandle_upload_progress, ) page.services.append(file_picker) page.add( ft.SafeArea( contentft.Column( controls[ ft.Button( contentSelect files..., iconft.Icons.FOLDER_OPEN, # 把选择动作挂在控件上——而不是在 on_click 里调用 # pick_files()——是对话框在 iOS 上能够打开的关键。 actionft.PickFiles(file_picker, allow_multipleTrue), ), 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)运行方式示例文件头部注明export FLET_SECRET_KEYsome_secret_key uv run flet run --web examples/services/file_picker/pick_files_action/main.py代码中有几个值得注意的实战细节e.files中的每个文件都带有name与size可直接用于渲染文件列表handle_result中通过len(e.files) 0判断是否禁用了上传按钮与空列表语义一致选中的文件仍关联在FilePicker上因此upload()无需重新接收文件对象只需按name或id构造FilePickerUploadFile并给出upload_urlpage.get_upload_url(fdir/{file.name}, 60)生成一个 60 秒有效的预签名上传 URLdir/前缀目录会在upload_dir下自动创建。与 pick_files() 返回值模式的对比为了彻底理解FilePickerResultEvent的定位下面再对比另一种不使用事件的结果获取方式。示例 pick_and_upload/main.py 展示了await file_picker.pick_files(allow_multipleTrue)直接拿到list[FilePickerFile]的写法该示例仅支持 Web 模式运行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) print(Picked files:, files) state.picked_files files upload_button.disabled len(files) 0 ...两种模式的本质区别在于结果传递通道pick_files()的返回值是一次性、同步地在await处取得调用方代码流清晰FilePickerResultEvent则是事件驱动的异步回调适用于无法把结果直接返回给调用方的PickFiles动作场景。需要文件内容的场景示例 pick_and_save_text_content/main.py 展示了with_dataTrue的用法——在 Web 模式下FilePickerFile.path不可用但bytes字段携带了文件内容可以直接解码读取files await ft.FilePicker().pick_files( allow_multipleFalse, with_dataTrue, file_typeft.FilePickerFileType.CUSTOM, allowed_extensions[txt, md], ) if not files: ... selected files[0] selected_file_content.value ( selected.bytes.decode(utf-8, errorsreplace) if selected.bytes else )对应地若FilePickerResultEvent场景下需要文件内容只需在PickFiles动作上设置with_dataTrue该动作在 file_picker.py 第 456-459 行将with_data透传给pick_files调用随后在on_result中通过f.bytes读取。总结FilePickerResultEvent是 Flet 文件选择在“客户端动作”模式下的结果载体它把PickFiles打开对话框后用户的选择以files: list[FilePickerFile]的形式送达FilePicker.on_result。理解它的关键在于三点触发源唯一只有PickFiles动作会触发它pick_files()直接返回列表而不触发事件空列表表示取消用户取消时e.files为[]用真假值即可判断与上传流程衔接选中的文件始终与FilePicker关联事件处理完成后可直接构造FilePickerUploadFile调用upload()。在 Web尤其是 iOS环境中把PickFiles动作挂在按钮上、在on_result里消费FilePickerResultEvent是让文件选择功能稳定工作的推荐做法。如需查看更多字段与完整 API可继续查阅 FilePickerFile 类型文档、FilePickerUploadEvent 类型文档 以及 FilePicker 服务文档。赞分享前端跨平台桌面应用移动开发【免费下载链接】fletBuild realtime web, mobile and desktop apps in Python only. No frontend experience required.项目地址https://gitcode.com/gh_mirrors/fl/flet点击查看免费下载相关推荐Flet TextSelection 详解文本选区模型、光标定位与选择事件编程指南Flet TextSelection 详解文本选区模型、光标定位与选择事件编程指南 导读 flet.TextSelection 是 Flet一个只用 Pyt前端跨平台桌面应用移动开发Flet TapEvent 事件负载详解在 Python 中精确处理点击、按下与抬起事件Flet TapEvent 事件负载详解在 Python 中精确处理点击、按下与抬起事件 TapEvent 是 Flet 中代表一次点击手势的事件负载类型前端跨平台桌面应用移动开发Wagtail 0.6 发布说明解读内置项目模板、wagtail start 命令与 RoutablePage 混入机制的起点Wagtail 0.6 发布说明解读内置项目模板、wagtail start 命令与 RoutablePage 混入机制的起点 本篇基于 Wagtail 0.前端跨平台桌面应用移动开发创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考