Skip to Content
Flet📁 File Operations

File Operations trong Flet

Học cách làm việc với files: chọn file, đọc/ghi, và upload. ⏱️ 20 phút

🎯 Mục tiêu

Nắm vững:

  • FilePicker - Chọn files
  • Đọc và ghi files
  • Upload files
  • Directory picker

📂 FilePicker với Declarative UI

import flet as ft @ft.observable class FileState: selected_files: str = "" def set_files(self, files_text: str): self.selected_files = files_text state = FileState() @ft.component def FilePickerDemo(file_picker: ft.FilePicker): return ft.Column([ ft.ElevatedButton( "Pick files", icon=ft.Icons.UPLOAD_FILE, on_click=lambda _: file_picker.pick_files(allow_multiple=True), ), ft.Text(state.selected_files or "No files selected"), ], spacing=20) def main(page: ft.Page): page.title = "File Picker" def pick_files_result(e: ft.FilePickerResultEvent): if e.files: state.set_files(", ".join([f.name for f in e.files])) else: state.set_files("Cancelled") file_picker = ft.FilePicker(on_result=pick_files_result) page.overlay.append(file_picker) page.add(FilePickerDemo(file_picker)) ft.run(main)

🔍 Lọc theo loại file

import flet as ft @ft.observable class ImagePickerState: selected_image: str = "" image_name: str = "" state = ImagePickerState() @ft.component def ImagePickerDemo(file_picker: ft.FilePicker): return ft.Column([ ft.Container( content=ft.Image(src=state.selected_image, fit=ft.ImageFit.CONTAIN) if state.selected_image else ft.Text("No image"), width=300, height=300, bgcolor=ft.Colors.GREY_200, alignment=ft.alignment.center, border_radius=10, ), ft.Text(state.image_name) if state.image_name else None, ft.ElevatedButton( "Choose image", icon=ft.Icons.IMAGE, on_click=lambda _: file_picker.pick_files( allowed_extensions=["png", "jpg", "jpeg", "gif"] ), ), ], spacing=15, horizontal_alignment=ft.CrossAxisAlignment.CENTER) def main(page: ft.Page): page.title = "Image Picker" def pick_image(e: ft.FilePickerResultEvent): if e.files: state.selected_image = e.files[0].path state.image_name = e.files[0].name file_picker = ft.FilePicker(on_result=pick_image) page.overlay.append(file_picker) page.vertical_alignment = ft.MainAxisAlignment.CENTER page.horizontal_alignment = ft.CrossAxisAlignment.CENTER page.add(ImagePickerDemo(file_picker)) ft.run(main)

📖 Đọc nội dung file

import flet as ft @ft.observable class TextFileState: content: str = "" file_name: str = "" error: str = "" def set_content(self, name: str, content: str): self.file_name = name self.content = content self.error = "" def set_error(self, error: str): self.error = error self.content = "" self.file_name = "" state = TextFileState() @ft.component def TextFileReader(file_picker: ft.FilePicker): return ft.Column([ ft.ElevatedButton( "Open text file", icon=ft.Icons.FILE_OPEN, on_click=lambda _: file_picker.pick_files( allowed_extensions=["txt", "md", "py"] ), ), ft.Text(state.file_name, weight=ft.FontWeight.BOLD) if state.file_name else None, ft.Container( content=ft.Text(state.content, selectable=True) if state.content else ft.Text(state.error, color=ft.Colors.RED) if state.error else ft.Text("Select a file to view content", color=ft.Colors.GREY), bgcolor=ft.Colors.GREY_100, padding=20, width=500, border_radius=10, ), ], spacing=15) def main(page: ft.Page): page.title = "Text File Reader" def pick_result(e: ft.FilePickerResultEvent): if e.files: file_path = e.files[0].path try: with open(file_path, "r", encoding="utf-8") as f: content = f.read() state.set_content(e.files[0].name, content[:1000]) # First 1000 chars except Exception as ex: state.set_error(f"Error: {ex}") file_picker = ft.FilePicker(on_result=pick_result) page.overlay.append(file_picker) page.padding = 30 page.add(TextFileReader(file_picker)) ft.run(main)

💾 Lưu file (Save As)

import flet as ft @ft.observable class EditorState: content: str = "" status: str = "" def set_content(self, text: str): self.content = text def set_status(self, status: str): self.status = status state = EditorState() @ft.component def TextEditor(file_picker: ft.FilePicker): return ft.Column([ ft.TextField( value=state.content, multiline=True, min_lines=8, hint_text="Enter your text here...", on_change=lambda e: state.set_content(e.control.value), ), ft.Row([ ft.ElevatedButton( "Save As", icon=ft.Icons.SAVE, on_click=lambda _: file_picker.save_file( file_name="document.txt", allowed_extensions=["txt"], ), ), ft.Text(state.status, color=ft.Colors.GREEN if "Saved" in state.status else ft.Colors.GREY), ]), ], spacing=15, expand=True) def main(page: ft.Page): page.title = "Text Editor" page.padding = 30 def save_result(e: ft.FilePickerResultEvent): if e.path: try: with open(e.path, "w", encoding="utf-8") as f: f.write(state.content) state.set_status(f"✅ Saved to: {e.path}") except Exception as ex: state.set_status(f"❌ Error: {ex}") else: state.set_status("Cancelled") file_picker = ft.FilePicker(on_result=save_result) page.overlay.append(file_picker) page.add(TextEditor(file_picker)) ft.run(main)

📁 Chọn thư mục

import flet as ft @ft.observable class FolderState: selected_path: str = "" state = FolderState() @ft.component def FolderPicker(file_picker: ft.FilePicker): return ft.Column([ ft.ElevatedButton( "Select Folder", icon=ft.Icons.FOLDER_OPEN, on_click=lambda _: file_picker.get_directory_path(), ), ft.Container( content=ft.Text(state.selected_path or "No folder selected"), bgcolor=ft.Colors.GREY_100, padding=15, border_radius=8, width=400, ), ], spacing=15) def main(page: ft.Page): page.title = "Folder Picker" page.padding = 30 def pick_folder(e: ft.FilePickerResultEvent): if e.path: state.selected_path = e.path file_picker = ft.FilePicker(on_result=pick_folder) page.overlay.append(file_picker) page.add(FolderPicker(file_picker)) ft.run(main)

⬆️ Upload file (Web)

Cho ứng dụng web, sử dụng upload:

import flet as ft @ft.observable class UploadState: is_uploading: bool = False status: str = "" progress: float = 0 def start_upload(self): self.is_uploading = True self.status = "Uploading..." self.progress = 0 def update_progress(self, progress: float, file_name: str): self.progress = progress if progress >= 1: self.is_uploading = False self.status = f"✅ Uploaded: {file_name}" state = UploadState() @ft.component def FileUploader(file_picker: ft.FilePicker): return ft.Column([ ft.ElevatedButton( "Upload", icon=ft.Icons.CLOUD_UPLOAD, on_click=lambda _: file_picker.pick_files(allow_multiple=True), ), ft.ProgressRing(visible=state.is_uploading), ft.ProgressBar(value=state.progress, visible=state.is_uploading), ft.Text(state.status), ], spacing=15) def main(page: ft.Page): page.title = "File Uploader" page.padding = 30 def upload_files(e: ft.FilePickerResultEvent): if e.files: state.start_upload() for f in e.files: upload_list = [ ft.FilePickerUploadFile( f.name, upload_url=page.get_upload_url(f.name, 600), ) ] file_picker.upload(upload_list) def upload_progress(e: ft.FilePickerUploadEvent): state.update_progress(e.progress, e.file_name) file_picker = ft.FilePicker( on_result=upload_files, on_upload=upload_progress, ) page.overlay.append(file_picker) page.add(FileUploader(file_picker)) ft.run(main, upload_dir="uploads")

📋 FilePicker Methods

MethodDescription
pick_files()Chọn files
save_file()Lưu file (Save As)
get_directory_path()Chọn thư mục
upload()Upload files (web)

⏭️ Tiếp theo

Tuyệt! Tiếp tục với Async Operations để xử lý bất đồng bộ.

Last updated on