Flet: Phím tắt cho lập trình viên Python để tạo giao diện Flutter hiệu năng cao

Programming tutorial - IT technology blog
Programming tutorial - IT technology blog

Tại sao Flet là “kẻ thay đổi cuộc chơi” cho GUI trong ngôn ngữ Python

Trong nhiều năm, các lập trình viên Python luôn rơi vào thế tiến thoái lưỡng nan. Bạn hoặc là sử dụng Tkinter, trông như một di vật từ thời Windows 95, hoặc phải vật lộn với lộ trình học tập đầy khó khăn của PyQt. Nếu muốn một giao diện hiện đại, bạn thường chuyển sang Electron. Tuy nhiên, Electron buộc bạn phải quản lý một instance Chromium nặng nề và viết JavaScript, khiến ngay cả những ứng dụng đơn giản cũng ngốn tới 200MB RAM hoặc hơn.

Flet phá vỡ vòng lặp này bằng cách đóng vai trò như một cầu nối. Nó cho phép bạn xây dựng các giao diện chuyên nghiệp bằng engine Flutter của Google mà không cần viết một dòng code Dart nào. Bạn chỉ cần viết Python thuần túy; Flet sẽ lo phần render. Tôi đã triển khai Flet trong thực tế cho các công cụ giám sát nội bộ. Nó cực kỳ ổn định, đặc biệt là đối với các dashboard dữ liệu lớn cần tốc độ xử lý nhanh.

So sánh Flet với các đối thủ cạnh tranh

Khi bắt đầu một dự án mới, tôi thường cân nhắc ba đối thủ chính:

  • Electron: UI đẹp nhưng ngốn tài nguyên. Nó yêu cầu một web stack (HTML/CSS/JS), làm tăng độ phức tạp cho backend Python.
  • PyQt/PySide: Trưởng thành và mang tính bản địa (native), nhưng việc tạo style rất cực khổ. QSS (Qt Style Sheets) thực chất là một phiên bản giới hạn và gây ức chế của CSS. Thêm vào đó, phí bản quyền thương mại có thể lên tới hơn 500 USD cho mỗi lập trình viên.
  • Flet: Sử dụng mô hình khai báo (declarative) của Flutter. Nó cực kỳ nhanh trong việc tạo prototype và chạy được trên desktop, web và mobile từ cùng một codebase. Tuyệt vời nhất là nó có giấy phép Apache 2.0 (miễn phí).

Đánh giá công tâm: Ưu và nhược điểm

Không có công cụ nào là hoàn hảo. Sau sáu tháng sử dụng Flet để xây dựng các dashboard DevOps, đây là thực tế về framework này.

Ưu điểm

  • Không còn mệt mỏi với CSS: Bạn xây dựng layout bằng các class Python như Row, Column, và Container. Đây là một sự giải thoát lớn nếu bạn không phải là chuyên gia front-end.
  • Khả năng chuyển đổi Web tức thì: Chỉ với một câu lệnh, ứng dụng desktop của bạn sẽ biến thành một ứng dụng web. Điều này hoàn hảo để chia sẻ các công cụ nội bộ qua URL.
  • Trạng thái phản ứng (Reactive State): Cập nhật UI rất đơn giản. Chỉ cần thay đổi một thuộc tính, gọi page.update(), và bạn đã hoàn tất.
  • Lặp lại nhanh chóng: Tính năng hot-reload cho cảm giác nhanh hơn nhiều so với các thư viện truyền thống. Bạn sẽ thấy các thay đổi chỉ trong vài miligiây.

Nhược điểm

  • Kích thước file thực thi ban đầu: Vì Flet đóng gói kèm engine Flutter, một file thực thi “Hello World” bắt đầu ở mức khoảng 60MB. Nó hơi nặng đối với các tiện ích nhỏ xíu.
  • Hạn chế về nền tảng: Bạn bị giới hạn trong các widget mà Flutter cung cấp. Nếu dự án của bạn yêu cầu can thiệp sâu vào hệ điều hành (low-level OS hooks) hoặc tương tác phần cứng đặc thù, PyQt vẫn là lựa chọn an toàn hơn.

Thiết lập môi trường

Tôi khuyên bạn nên sử dụng môi trường ảo (virtual environment) để giữ hệ thống sạch sẽ. Flet yêu cầu Python 3.7 trở lên. Việc thiết lập mất chưa đầy hai phút.

# Tạo và kích hoạt môi trường ảo
python -m venv venv
source venv/bin/activate  # Trên Windows sử dụng: .\venv\Scripts\activate

# Cài đặt thư viện
pip install flet

Tôi cũng gợi ý cài đặt extension Flet cho VS Code. Nó cung cấp các đoạn code mẫu (snippets) giúp bạn không phải gõ đi gõ lại các đoạn code khung (boilerplate) nhiều lần.

Xây dựng ứng dụng Giám sát Hệ thống thực tế

Hãy cùng xây dựng một thứ gì đó hữu ích: một dashboard trực tiếp cho CPU và RAM. Ví dụ này làm nổi bật cách Flet xử lý dữ liệu thời gian thực và tạo kiểu giao diện.

import flet as ft
import psutil
import threading
import time

def main(page: ft.Page):
    page.title = "Giám sát Hệ thống Pro"
    page.theme_mode = ft.ThemeMode.DARK
    page.window_width, page.window_height = 400, 450
    
    # Định nghĩa các thành phần UI
    cpu_text = ft.Text("CPU: 0%", size=20, weight="bold")
    ram_text = ft.Text("RAM: 0%", size=20, weight="bold")
    cpu_bar = ft.ProgressBar(width=300, color="blue")
    ram_bar = ft.ProgressBar(width=300, color="green")

    def refresh_stats():
        while True:
            cpu = psutil.cpu_percent()
            ram = psutil.virtual_memory().percent
            
            cpu_text.value, cpu_bar.value = f"CPU: {cpu}%", cpu / 100
            ram_text.value, ram_bar.value = f"RAM: {ram}%", ram / 100
            
            page.update()
            time.sleep(1)

    page.add(
        ft.Column([
            ft.Icon(name=ft.icons.DASHBOARD, size=50, color="blue"),
            ft.Text("Hiệu năng", size=28, weight="bold"),
            ft.Divider(),
            cpu_text, cpu_bar,
            ft.Container(height=10),
            ram_text, ram_bar,
        ], horizontal_alignment="center")
    )

    threading.Thread(target=refresh_stats, daemon=True).start()

ft.app(target=main)

Giải thích mã nguồn

Đối tượng page chính là cửa sổ của bạn. Chúng ta sử dụng ft.Column để xếp chồng các phần tử theo chiều dọc, tương tự như Flexbox trong thiết kế web. Logic rất đơn giản: một luồng chạy ngầm (background thread) lấy dữ liệu qua psutil, cập nhật các thuộc tính của đối tượng và kích hoạt page.update(). Nó sạch sẽ, dễ đọc và tránh được tình trạng “callback hell” thường thấy trong các framework cũ.

Điều hướng đa trang

Ứng dụng hiếm khi chỉ nằm trên một màn hình. Flet sử dụng hệ thống định tuyến (routing) kiểu URL giúp việc điều hướng mang lại cảm giác như đang lướt web. Đây là cách tôi cấu trúc các công cụ có nhiều view:

def main(page: ft.Page):
    def route_change(e):
        page.views.clear()
        page.views.append(
            ft.View("/", [ 
                ft.AppBar(title=ft.Text("Trang chủ")),
                ft.ElevatedButton("Cài đặt", on_click=lambda _: page.go("/settings")) 
            ])
        )
        if page.route == "/settings":
            page.views.append(
                ft.View("/settings", [ 
                    ft.AppBar(title=ft.Text("Cài đặt")),
                    ft.ElevatedButton("Quay lại", on_click=lambda _: page.go("/")) 
                ])
            )
        page.update()

    page.on_route_change = route_change
    page.go("/")

Mẫu thiết kế này giúp code của bạn luôn ngăn nắp khi dự án phát triển. Tôi đã sử dụng chính cấu trúc này cho các công cụ triển khai cần các view riêng biệt để chỉnh sửa cấu hình và xem log stream.

Đóng gói và Phân phối

Khi bạn đã sẵn sàng chia sẻ ứng dụng của mình, bạn chắc chắn không muốn yêu cầu người dùng phải cài đặt Python. Flet giúp việc đóng gói trở nên đơn giản. Đầu tiên, hãy cài đặt các công cụ build:

pip install flet[all]

Để tạo một ứng dụng Windows độc lập, hãy chạy:

flet build windows

Lệnh này sẽ tạo ra một file thực thi trong thư mục build/windows. Lưu ý rằng bạn phải thực hiện build trên chính hệ điều hành mục tiêu: để có bản bundle .app cho macOS, bạn cần chạy lệnh này trên máy Mac.

Lời kết

Chuyển từ các đoạn script sang ứng dụng GUI là một bước tiến lớn đối với bất kỳ kỹ sư IT nào. Flet giúp hạ thấp rào cản đó một cách đáng kể. Nó đủ ổn định cho các phần mềm nội bộ cấp độ production và hưởng lợi từ một engine đã được kiểm chứng qua thực tế. Nếu bạn cần một công cụ trông chuyên nghiệp và hỗ trợ dark mode mặc định — mà không cần học cả một web stack mới — Flet chính là con đường hiệu quả nhất dành cho các lập trình viên Python.

Share: