Как создать адаптивную кнопку в Flet с помощью Python

    Flet - это мощный фреймворк для создания кроссплатформенных приложений на Python. Одна из частых задач разработчика - создание кастомной кнопки с адаптивной вёрсткой. В этой статье мы разберём готовый пример функции button1, которая создаёт интерактивный элемент интерфейса, и объясним, как правильно позиционировать компоненты с помощью ft.ResponsiveRow и ft.ResponsiveView.

    Разбор кода: структура кнопки

    Функция button1 принимает четыре параметра: объект страницы (page), текст кнопки (text), цвет текста (color) и функцию-обработчик (function). Внутри используется ft.Container с атрибутом on_click, что делает элемент кликабельным. Основной контент - ft.ResponsiveRow, который отвечает за адаптивность.

    Параметры адаптивности и колонки

    Вложенный контейнер имеет свойство aspect_ratio=4.4 - это соотношение ширины к высоте. Параметр col задаёт количество колонок, которые элемент занимает на разных разрешениях экрана:

    • XS (мобильные устройства) - 11 колонок из 12 (почти вся ширина)
    • LG (большие экраны) - 2.8 колонки (узкий блок)

    Это позволяет кнопке быть компактной на десктопе и растягиваться на телефоне.

    Использование ft.Stack для наложения элементов

    Внутри контейнера находится ft.Stack, который позволяет накладывать виджеты друг на друга. Первым слоем идёт ft.Image с фоновым изображением (bgforbt.png), вторым - ft.Text с заданными параметрами: жирный шрифт (weight=ft.FontWeight.BOLD), размер 16 и выравнивание по центру. Благодаря alignment=ft.Alignment.CENTER текст располагается ровно посередине фона.

    Почему не работает ft.ResponsiveView?

    Многие разработчики путают ft.ResponsiveRow и ft.ResponsiveView. Первый используется для создания адаптивных сеток внутри контейнера, а второй - как корневой элемент страницы. Если вы пытаетесь позиционировать кнопку через ft.ResponsiveView, но ничего не получается, проверьте:

    • Правильное размещение: ResponsiveView должен быть самым внешним элементом, а не обёрткой для отдельной кнопки.
    • Настройки колонок: Убедитесь, что для каждого дочернего элемента задан параметр col с брейкпоинтами (XS, SM, MD, LG).
    • Отсутствие конфликта: ResponsiveRow уже управляет шириной элементов, поэтому не стоит дублировать его внутри ResponsiveView без необходимости.

    Если вы используете ft.ResponsiveView как корневой элемент страницы, а кнопка всё равно не адаптируется - проверьте, что все дочерние элементы имеют явно указанные col. Без этого фреймворк не сможет распределить пространство.

    Пример рабочего кода с ResponsiveView

    Вот как можно правильно встроить нашу кнопку в адаптивную страницу:

    import flet as ft
    
    def main(page: ft.Page):
        page.add(
            ft.ResponsiveView(
                [
                    ft.Container(
                        content=ft.ResponsiveRow(
                            [
                                button1(page, 'Нажми меня', ft.Colors.WHITE, lambda e: print('Клик!'))
                            ],
                            alignment=ft.MainAxisAlignment.CENTER
                        ),
                        expand=True
                    )
                ]
            )
        )
    
    ft.app(target=main)

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

    Советы по отладке адаптивности

    Если кнопка отображается некорректно, выполните следующие шаги:

    • Проверьте пути к ресурсам: Файл bgforbt.png должен лежать в папке assets/images/ относительно корня проекта.
    • Используйте цветные границы: Добавьте временно border=ft.border.all(1, ft.Colors.RED) к контейнерам, чтобы видеть их границы.
    • Логируйте размеры окна: Выведите page.window.width в консоль, чтобы понять, на каком разрешении вы тестируете.

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

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