Адаптивная верстка во Flet: как задать размеры в процентах
При разработке кроссплатформенных приложений на Python с помощью фреймворка Flet разработчики часто сталкиваются с задачей адаптивного расположения элементов. В отличие от веб-верстки, где можно напрямую указать width: 50%, во Flet нет встроенной поддержки процентных значений для свойств width и height. Однако эту проблему можно решить программно, используя размеры окна приложения. Рассмотрим основные подходы и типичные ошибки.
Почему прямое указание процентов не работает во Flet?
Flet - это фреймворк для создания интерфейсов на базе Flutter, который оперирует пиксельными значениями (числами типа int или float). Свойства width и height принимают конкретные числовые значения, а не строки с процентами. Поэтому конструкция width='50%' вызовет ошибку или будет проигнорирована.
Программный расчет на основе размеров окна
Самый популярный способ - использовать свойства объекта page.window. Например, чтобы задать высоту блока, равную 15.8% от высоты окна, пишут:
height=page.window.height * 0.158Однако такой код часто срабатывает некорректно. Основные причины: обращение к page.window до полной инициализации окна или использование устаревшего API. Начиная с версии 0.21.0 Flet, рекомендуется использовать page.window_height и page.window_width.
Правильный способ: использование page.window_height
В современных версиях Flet размеры окна доступны через прямые свойства page.window_height и page.window_width. Пример рабочего кода:
import flet as ft
def main(page: ft.Page):
def update_size(e):
container.height = page.window_height * 0.158
container.update()
container = ft.Container(
width=page.window_width * 0.5,
height=page.window_height * 0.158,
bgcolor=ft.colors.BLUE_200
)
page.on_resized = update_size
page.add(container)
ft.app(target=main)Обратите внимание: мы используем событие on_resized, чтобы пересчитывать размеры при изменении окна. Это гарантирует адаптивность.
Альтернативы: Flex, Column и Row с expand
Если вам не нужна точная процентная привязка, рассмотрите встроенные механизмы Flet для создания адаптивных макетов:
- Column и Row с параметром expand: позволяет распределять пространство между дочерними элементами в долях.
- Flex-виджеты:
ft.Flexиft.ResponsiveRowдля создания гибких сеток. - Alignment и padding: для точного позиционирования без жестких размеров.
Пример использования expand для создания двух колонок, занимающих 30% и 70% ширины:
row = ft.Row([
ft.Container(expand=3, bgcolor=ft.colors.RED),
ft.Container(expand=7, bgcolor=ft.colors.GREEN)
])Здесь общий коэффициент expand = 10, первый контейнер получает 3/10 (30%), второй - 7/10 (70%).
Частые ошибки и их решение
- Ошибка: элемент не отображается или имеет нулевой размер. Решение: убедитесь, что вы обращаетесь к
page.window_heightпосле того, как страница загружена. Используйтеpage.on_resizedили инициализацию в колбэкеpage.on_ready. - Ошибка: размеры не обновляются при изменении окна. Решение: подпишитесь на событие
page.on_resizedи вызывайтеupdate()для изменяемых виджетов. - Ошибка: дробные значения приводят к артефактам. Решение: округляйте результат до целого числа с помощью
int().
Заключение
Хотя во Flet нет прямых процентов, адаптивный дизайн достигается программным расчетом через page.window_height и page.window_width, а также использованием expand и гибких макетов. Главное - правильно инициализировать размеры и реагировать на изменение окна. Это позволяет создавать интерфейсы, которые корректно отображаются на разных экранах без привязки к конкретным моделям устройств.