Маршрутизация и навигация в Flet для Python-разработчиков

Специализированный курс для бэкенд-разработчиков, желающих освоить создание многостраничных интерфейсов на Flet. Вы научитесь управлять URL-адресами, работать со стеком представлений (Views) и создавать навигационные панели без глубоких знаний фронтенда.

1. Установка Flet и базовая структура приложения

Установка Flet и базовая структура приложения

Добро пожаловать в курс по маршрутизации и навигации в Flet. Прежде чем мы начнем создавать сложные многостраничные интерфейсы, нам необходимо заложить прочный фундамент. В этой статье мы разберем, что такое Flet, как его установить и из каких кирпичиков строится любое приложение на этом фреймворке.

Почему Flet — идеальный выбор для Python-разработчика

Если вы привыкли писать скрипты, работать с данными или создавать backend-логику, мир frontend-разработки может показаться хаотичным: HTML для структуры, CSS для стилей, JavaScript для логики, плюс бесконечные сборщики и фреймворки (React, Vue, Angular).

Flet решает эту проблему радикально. Это обертка над Flutter — мощным UI-тулкитом от Google. Главная особенность Flet в том, что он транслирует ваш Python-код в виджеты Flutter в реальном времени. Вы пишете на чистом Python, используете привычные ООП-паттерны, а на выходе получаете современное реактивное приложение, которое работает на Windows, macOS, Linux, iOS, Android и в браузере.

!Архитектура Flet: один код на Python превращается в нативный UI на разных платформах

Установка и настройка окружения

Для работы с Flet вам понадобится Python версии 3.7 или выше. Процесс установки максимально прост и не требует настройки сложных SDK (в отличие от чистого Flutter).

Откройте терминал и выполните команду:

Этой команды достаточно для начала работы на Windows и macOS.

Особенности для Linux и WSL

Если вы работаете на Linux или используете WSL (Windows Subsystem for Linux), вам может потребоваться библиотека GStreamer для корректного отображения мультимедиа и окон. Если при запуске вы увидите ошибку, связанную с libgstapp, выполните установку зависимостей (для Ubuntu/Debian):

Подробнее об установке на специфических системах можно прочитать в документации или руководствах сообщества ixbt.com.

Анатомия Flet-приложения

Минимальное приложение на Flet состоит из трех ключевых компонентов:

  • Импорт библиотеки.
  • Функция main — точка входа, которая принимает объект страницы.
  • Запуск приложения через ft.app.
  • Рассмотрим простейший пример «Hello, World!»:

    Разбор компонентов

    #### Объект page: ft.Page

    Это ваш холст. В терминологии веб-разработки это аналог window или document.body. Объект page хранит состояние текущего окна, список отображаемых элементов и настройки темы.

    Ключевые свойства page: * page.title: Заголовок окна браузера или программы. * page.route: Текущий URL-путь (критически важно для нашего курса по навигации). * page.controls: Список элементов, добавленных на страницу. * page.update(): Метод, который отправляет изменения из Python-кода на экран пользователя.

    #### Элементы управления (Controls)

    В Flet все визуальные компоненты называются Controls (в Flutter они называются виджетами). Это обычные Python-классы. В примере выше мы использовали ft.Text.

    Другие базовые контролы: * ft.ElevatedButton: Кнопка с тенью. * ft.TextField: Поле ввода текста. * ft.Icon: Иконка.

    #### Метод page.add()

    Этот метод делает две вещи: добавляет контрол в список page.controls и автоматически вызывает обновление страницы. Если вы изменяете свойства уже добавленного элемента, вам нужно вызывать page.update() вручную.

    Интерактивность и обновление состояния

    Статический текст — это скучно. Давайте добавим интерактивности. Поскольку вы знакомы с ООП, структура Flet покажется вам родной: мы создаем объекты, меняем их атрибуты и просим систему перерисовать интерфейс.

    Рассмотрим пример счетчика, который демонстрирует цикл обновления:

    !Цикл обновления интерфейса в Flet

    Важное правило page.update()

    Flet не отслеживает изменения переменных автоматически (как это делают некоторые JS-фреймворки через прокси). Вы должны явно сказать: «Я изменил состояние этого объекта, перерисуй его».

    * page.add(control) — добавляет и обновляет автоматически. * control.value = "New" — меняет данные только в памяти Python. * page.update() — синхронизирует память Python с экраном пользователя.

    Базовая компоновка: Row и Column

    Прежде чем переходить к навигации между страницами, нужно научиться верстать одну страницу. Два главных инструмента для этого — Row (Строка) и Column (Колонка).

    * Column: размещает элементы вертикально (сверху вниз). Это поведение по умолчанию для самой страницы, если не указано иное. * Row: размещает элементы горизонтально (слева направо).

    Оба этих контейнера имеют свойство controls (список вложенных элементов) и свойства выравнивания (alignment).

    Пример вложенности:

    Это создает вертикальный список, где под текстом находятся две кнопки в один ряд. Понимание вложенности Row и Column критически важно для создания сложных макетов pythontalk.olegtalks.ru.

    Режимы запуска: Десктоп и Веб

    Одной из киллер-фич Flet является возможность запускать один и тот же код как нативное приложение или как веб-сайт.

    По умолчанию ft.app(target=main) открывает нативное окно ОС. Чтобы открыть приложение в браузере, измените вызов:

    Это полезно при отладке, так как позволяет использовать инструменты разработчика браузера (F12) для инспекции элементов, хотя Flet предоставляет и свои инструменты отладки.

    Подготовка к маршрутизации

    Сейчас мы работаем в рамках одной функции main и одной «физической» страницы. Все элементы добавляются в общий список page.controls.

    Однако, когда приложение растет, нам нужно показывать пользователю разные экраны (например, «Вход», «Список товаров», «Корзина»). В классическом вебе это делается через смену URL. В Flet мы будем использовать механизм Routing (маршрутизации).

    В следующих статьях мы научимся:

  • Очищать страницу и загружать новые контролы при смене маршрута.
  • Использовать page.on_route_change для отслеживания навигации.
  • Создавать абстракции View для управления экранами.
  • Итоги

    * Flet позволяет писать кроссплатформенные UI-приложения на чистом Python, используя мощь Flutter под капотом. * Основной структурной единицей является ft.Page, на которую мы добавляем Controls (элементы управления). * Для изменения интерфейса после инициализации необходимо явно вызывать метод page.update(). * Компоновка строится на базе вложенных контейнеров Row (строка) и Column (колонка). * Приложение запускается функцией ft.app(target=main), которая может открывать как десктопное окно, так и веб-страницу.

    2. Основы маршрутизации: работа с page.route и page.go

    Основы маршрутизации: работа с page.route и page.go

    В предыдущей статье мы научились создавать простые одностраничные приложения. Однако большинство реальных программ требуют наличия нескольких экранов: авторизации, настроек, списка товаров и детального просмотра.

    В Flet навигация построена на изменении URL-адреса, даже если ваше приложение работает как десктопная программа на Windows или macOS. В этой статье мы разберем механизм переключения между экранами, используя свойства page.route и метод page.go.

    Логика маршрутизации в Flet

    В отличие от веб-фреймворков (Django, Flask), где каждый URL обрабатывается отдельной функцией-контроллером, Flet работает как SPA (Single Page Application). Это означает, что у вас есть одно окно (page), содержимое которого полностью перерисовывается при изменении адреса.

    Процесс навигации состоит из трех этапов:

  • Инициация: Вы вызываете метод смены маршрута.
  • Событие: Flet фиксирует изменение адреса и вызывает специальный обработчик.
  • Отрисовка: Обработчик очищает текущий экран и добавляет элементы, соответствующие новому адресу.
  • !Цикл обработки изменения маршрута

    Ключевые инструменты навигации

    Для управления маршрутами нам понадобятся три основных элемента класса Page.

    1. Свойство page.route

    Это строковая переменная, которая хранит текущий путь приложения.

    * При запуске приложения page.route обычно равен "/". * Вы можете прочитать это свойство, чтобы узнать, где находится пользователь. * Важно: Прямое присваивание page.route = "/new" не переключит экран автоматически. Оно лишь изменит значение переменной.

    2. Метод page.go(route)

    Это основной метод для навигации. Он делает две вещи:

  • Меняет значение page.route и URL в адресной строке (если это веб).
  • Добавляет запись в историю браузера (чтобы работала кнопка «Назад»).
  • Триггерит событие изменения маршрута.
  • Пример вызова:

    3. Обработчик page.on_route_change

    Это функция, которую вы должны написать сами. Она будет вызываться каждый раз, когда срабатывает page.go или когда пользователь меняет URL вручную в браузере. Именно здесь происходит магия подмены экранов.

    Работа со списком page.views

    В прошлой статье мы добавляли элементы напрямую в page.controls. При использовании маршрутизации мы меняем подход. Теперь мы используем page.views.

    page.views — это список (стек) экранов. * Последний элемент этого списка — это то, что видит пользователь прямо сейчас. * Предыдущие элементы хранятся «под низом» (это нужно для корректной анимации возврата назад на мобильных устройствах).

    Класс ft.View

    Каждый экран описывается объектом ft.View. Это контейнер, похожий на саму Page, но для конкретного маршрута. У него есть свой маршрут, список контролов и настройки AppBar.

    Практический пример: Двухстраничное приложение

    Давайте соберем все вместе. Мы создадим приложение с главной страницей (/) и страницей настроек (/settings).

    Разбор кода

  • page.views.clear(): Мы очищаем стек представлений перед перерисовкой. Это упрощенный подход. В сложных приложениях вы можете не очищать стек полностью, а аккуратно управлять историей, но для старта clear() + пересборка — самый надежный вариант.
  • Условие if page.route == "/settings": Обратите внимание, что мы сначала добавляем View главной страницы, и только потом, если нужно, View настроек. Это создает правильную историю навигации: Главная -> Настройки.
  • page.on_view_pop: Это событие срабатывает, когда пользователь нажимает системную кнопку «Назад» (в браузере или на Android). Мы удаляем верхний слой (pop) и переходим на маршрут предыдущего слоя.
  • Передача параметров в URL

    Часто нам нужно не просто перейти на страницу, а передать данные (например, id товара: /product/42).

    page.route — это просто строка. Flet из коробки не парсит её автоматически (как это делает FastAPI), но вы можете использовать стандартные методы Python или библиотеку flet-route (о которой мы поговорим в будущих статьях).

    Простейший способ обработки параметров с использованием стандартных средств Python:

    Класс TemplateRoute помогает извлекать переменные из строки пути, избавляя вас от написания сложных регулярных выражений вручную. Подробнее о шаблонах путей можно прочитать в документации Flet.

    Итоги

    * Маршрутизация в Flet строится вокруг изменения строки page.route. * Для перехода на новую страницу используйте метод page.go("/path"). * Вся логика отрисовки экранов должна находиться в функции-обработчике page.on_route_change. * Вместо прямого добавления контролов на страницу (page.add), мы формируем список page.views, состоящий из объектов ft.View. * Для корректной работы кнопки «Назад» необходимо обрабатывать событие page.on_view_pop.