Адаптивная верстка во 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 и гибких макетов. Главное - правильно инициализировать размеры и реагировать на изменение окна. Это позволяет создавать интерфейсы, которые корректно отображаются на разных экранах без привязки к конкретным моделям устройств.

    Часто задаваемые вопросы