Баннер мобильный (3) Пройти тест

Flet: удобный фреймворк для создания приложений

Как легко создавать приложения на Python

Инструменты

29 мая 2024

Поделиться

Скопировано
Flet: удобный фреймворк для создания приложений

Содержание

    Расскажем, что такое Flet и как на нем создавать приложения. В качестве примера рассмотрим простое приложение для создания гороскопов.

    Что такое Flet и для чего он нужен

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

    Flet основан на Flutter и предоставляет разработчикам готовые компоненты для конструирования GUI — графического интерфейса пользователя. Создатели Flet не только используют готовые компоненты из Flutter, но и пишут свои. Программы пока можно писать только на Python, но создатели обещают добавить и другие языки программирования. Подробнее о Flet можно узнать на официальном сайте

    Создадим приложение для составления гороскопов и разберемся, как разрабатывать приложения с использованием фреймворка Flet. Начнем с установки IDE — среды разработки.

    Установка IDE и создание проекта

    Так как приложение будет писаться на Python, то в качестве среды разработки идеально подойдет PyCharm от компании JetBrains. Другие IDE для разработки на Python можно выбрать в нашей подборке.

    Установка IDE

    Скачать ее можно здесь. Предварительно нужно выбрать свою операционную систему и только потом загружать файл. Скачивать следует бесплатную версию Community Edition. Она разрабатывается сообществом и ее возможностей с лихвой хватит для создания несложных проектов.

    У владельцев устройств на Windows и MacOS установка не должна вызывать каких-либо трудностей. Там все стандартно. Для пользователей Linux среда поставляется в виде архива TAR.GZ и его нужно сначала распаковать. Обычно его распаковывают в домашнюю папку, но это не обязательное требование.

    После распаковки заходим в папку и ищем там подпапку bin, а в ней файл pycharm.sh:

    Папка PyCharm
    Источник: автор статьи

    Запускаем этот скрипт как приложение. При помощи клика правой кнопкой мыши вызываем контекстное меню и в нем выбираем пункт «Запустить как приложение». После принятия лицензионного соглашения перед нами должно появиться стартовое окно среды:

    Welcome to PyCharm
    Источник: автор статьи

    Для того чтобы значок IDE отображался в меню приложений, следует нажать на символ шестеренки в нижнем левом углу и в открывшемся списке выбрать пункт «Create Desktop Entry…».

    Создание проекта

    Нажимаем на «New Project» и в появившемся окне вводим название проекта (zodiac), выбираем месторасположение проекта, а также отмечаем правый чекбокс, чтобы среда создала для нас приветственный скрипт. Все остальные настройки оставляем как есть:

    Создание нового проекта pycharm
    Источник: автор статьи

    Теперь можно смело жать на кнопку «Create». После открытия проекта нажимаем на зеленый треугольник в верхней части окна. Запустится приветственный скрипт:

    Главный файл main.py
    Источник: автор статьи

    Мы проверили, что все работает как надо. Теперь эти строки можно удалить. Нам они больше не понадобятся. Вместо них следует ввести:

    def main(page: Page):
        pass
    
    app(main)

    Это базовая структура приложения. На месте ключевого слова pass будет находиться весь код приложения. Для начала можно создать заголовок окна:

    def main(page: Page):
        page.title = "Zodiac"
    
    app(main)

    Теперь поговорим об интерфейсе приложения.

    Интерфейс приложения

    Приложение состоит из двух страниц. На первой странице пользователь вводит данные, а на второй — получает результат. Для вычислений приложение использует библиотеку Kerykeion. Гороскоп получается в формате векторного изображения (SVG). Дополнительно выводится сводная таблица гороскопа. Первая страница приложения имеет такой вид:

    Интерфейс приложения на Flet
    Источник: автор статьи

    Вторая страница:

    Сводная таблица гороскопа
    Источник: автор статьи

    Исходный код приложения можно посмотреть здесь

    Отображение страниц

    Для отображения страниц применяется такая функция:

    def route_change(e):
            page.views.clear()
            page.views.append(
                View(
                    "/",
                    [
                        AppBar(title=Text("Ввод данных"), bgcolor=colors.GREEN_100),
                        input_column
                    ],
                    scroll=ScrollMode.ADAPTIVE
                )
            )
            if page.route == "/result":
                page.views.append(
                    View(
                        "/result",
                        [
                            AppBar(title=Text("Результат"), bgcolor=colors.BLUE_100),
                            output_column
                        ],
                        scroll=ScrollMode.ADAPTIVE
                    )
                )
            page.update()

    Каждая отдельная страница представляет собой контейнер View, состоящий из компонента AppBar и контейнера Column. Для страницы ввода данных этот контейнер (input_column) состоит из нескольких полей ввода (TextField) и кнопок (ElevatedButton), а для страницы вывода результата контейнер output_column составляется из компонента Image для отображения картинки и Text для вывода текста. Для переключения страниц применяется следующая функция:

        def view_pop(e):
            page.views.pop()
            top_view = page.views[-1]
            page.go(top_view.route)

    Она вызывается в самом конце скрипта вместе с route_change:

    page.on_route_change = route_change
        page.on_view_pop = view_pop
        page.go(page.route)

    Элементы страниц и контейнеры

    Сами элементы страниц и контейнеры создаются таким образом:

        name_tf = TextField(label="Имя", autofocus=True)
        day_tf = TextField(label="День рождения")
        month_tf = TextField(label="Месяц рождения")
        year_tf = TextField(label="Год рождения")
        date_button = ElevatedButton(
            "Выбор даты рождения",
            icon=icons.CALENDAR_MONTH,
            on_click=lambda _: date_picker.pick_date(),
        )
        hours_tf = TextField(label="Время рождения(часы)")
        minutes_tf = TextField(label="Время рождения(минуты)")
        time_button = ElevatedButton(
            "Выбор времени рождения",
            icon=icons.LOCK_CLOCK,
            on_click=lambda _: time_picker.pick_time(),
        )
        place_tf = TextField(label="Место рождения")
        path_tf = TextField(label="Место сохранения файла")
        path_button = ElevatedButton(
            "Выбор места сохранения файла",
            icon=icons.FOLDER_OPEN,
            on_click=lambda _: file_picker.get_directory_path()
        )
        b = ElevatedButton(text="ПОКАЗАТЬ ГОРОСКОП", on_click=button_clicked)
        t = Text(size=15, selectable=True)
        image = Image(src="***", width=1000, height=600)
    
        input_column = Column(
            [name_tf, day_tf, month_tf, year_tf, date_button, hours_tf, minutes_tf, time_button, place_tf, path_tf,
            path_button, b])
        output_column = Column([image, t])
    

    Здесь мы последовательно создаем отдельно каждый элемент страницы, а потом упаковываем их в два отдельных Column, которые передаем в контейнеры View. 

    Диалоговые окна

    В программе также используются диалоги для выбора даты рождения, времени рождения и места сохранения файла с готовым гороскопом. Эти диалоги привязываются к определенным кнопкам, а их код выглядит так:

        date_picker = DatePicker(
            confirm_text="Подтвердить",
            cancel_text="Отмена",
            error_invalid_text="Дата вне диапазона",
            help_text="Выберите дату",
            on_change=change_date
        )
    
        time_picker = TimePicker(
            confirm_text="Подтвердить",
            cancel_text="Отмена",
            error_invalid_text="Время вне диапазона",
            help_text="Выберите время",
            on_change=change_time
        )
    
        file_picker = FilePicker(on_result=on_picker_result)
    
        page.overlay.append(date_picker)
        page.overlay.append(time_picker)
        page.overlay.append(file_picker)

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

        def change_date(e):
            day_tf.value = str(date_picker.value.day)
            month_tf.value = str(date_picker.value.month)
            year_tf.value = str(date_picker.value.year)
            page.update()
    
        def change_time(e):
            hours_tf.value = str(time_picker.value.hour)
            minutes_tf.value = str(time_picker.value.minute)
            page.update()
    
        def on_picker_result(e: FilePickerResultEvent):
            path_tf.value = e.path
            page.update()

    Диалоговое окно выбора даты выглядит так:

    Выбор даты
    Источник: автор статьи

    Для выбора времени используется такой диалог:

    Выбор времени
    Источник: автор статьи

    Для выбора места сохранения гороскопа используется инструмент выбора файлов, зависящий от операционной системы и рабочего окружения. Например, в среде GNOME средство выбора директории выглядит так:

    Выбор директории
    Источник: автор статьи

    Всплывающие сообщения и импорты

    Иногда нужно сообщать пользователю об ошибках. Например, если он ввел некорректные данные или вообще забыл их ввести. Для таких сообщений используется компонент SnackBar:

        def show_snack_bar(msg):
            snack_bar = SnackBar(content=Text(msg), bgcolor=colors.RED)
            page.snack_bar = snack_bar
            snack_bar.open = True

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

    SnackBar
    Источник: автор статьи

    Для того чтобы использовать все перечисленные компоненты, в самом начале исходника необходимо произвести соответствующий импорт:

    from flet import View, AppBar, ElevatedButton, Page, Text, TextField, Image, DatePicker, TimePicker, FilePicker, FilePickerResultEvent, SnackBar, Column, ScrollMode, colors, icons, app

    Удобство IDE PyCharm в том, что она сама предложит и установит все необходимые библиотеки. Разработчику об этом не нужно особо беспокоиться. От него потребуется только подтвердить установку. Так, при попытке импорта компонентов из flet среда предложит установить необходимый пакет. С интерфейсом закончили. Теперь поговорим о том, как приложение создает гороскопы.

    Создание гороскопов

    Как уже говорилось, приложение использует библиотеку Kerykeion для построения гороскопов. Прежде чем ее использовать сначала нужно сделать такой импорт:

    from kerykeion import AstrologicalSubject, KerykeionChartSVG, Report

    Также понадобятся еще и эти импорты:

    from datetime import datetime
    from pathlib import Path

    Весь код создания гороскопов содержится в этой функции:

    def button_clicked(e):
        if (len(name_tf.value.strip()) == 0 or len(day_tf.value.strip()) == 0 or len(year_tf.value.strip()) == 0 or
                    len(hours_tf.value.strip()) == 0 or len(minutes_tf.value.strip()) == 0 or
                    len(place_tf.value.strip()) == 0):
                show_snack_bar("Заполните все поля!")
                page.update()
                return
    
            name = name_tf.value
            day = int(day_tf.value)
            month = int(month_tf.value)
            year = int(year_tf.value)
            hours = int(hours_tf.value)
            minutes = int(minutes_tf.value)
            place = place_tf.value
    
            if not is_valid_date_time(day, month, year, hours, minutes):
                show_snack_bar("Введите корректные значения даты и времени рождения")
                page.update()
                return
    
            path = Path(path_tf.value)
    
            if not path.exists():
                show_snack_bar("Путь до места сохранения файла не существует")
                page.update()
                return
    
            subject = AstrologicalSubject(name, year, month, day, hours, minutes, place)
            chart = KerykeionChartSVG(subject, chart_type="Natal")
    
            if not len(path_tf.value.strip()) == 0:
                chart.set_output_directory(path)
    
            chart.makeSVG()
    
            report = Report(subject)
    
            t.value = report.get_full_report()
    
            image.src = chart.chartname
    
            page.go("/result")
    

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

    def is_valid_date_time(day, month, year, hours, minutes):
            try:
                datetime(year, month, day, hours, minutes)
                return True
            except ValueError:
                return False
    

    Дальше создается переменная path, в которой будет храниться место сохранения файла гороскопа. На следующем шаге проверяется существование этого места. Теперь, когда все необходимые переменные созданы и в них записаны все нужные данные, настало время их использовать.

    С помощью  класса AstrologicalSubject создается объект subject. На вход конструктора класса подаются все переменные, кроме path. Далее создается объект chart. Для его создания используется KerykeionChartSVG и ему на вход передаются subject и тип гороскопа. На следующем этапе устанавливается путь до места сохранения гороскопа. Если путь указан, то он передается в функцию set_output_directory, которая применяется к объекту chart. Теперь ничего не мешает создать гороскоп. Он создается функцией makeSVG, вызванной для chart, и вследствие ее выполнения в указанной директории должен появиться файл с готовым гороскопом. Если пользователь не указал путь до места сохранения файла, то по умолчанию файл будет создан в домашней директории пользователя.

    Осталось только создать таблицу. Для ее создания применяется класс Report, которому на вход подается subject. Следующая команда отображает содержимое report в текстовой области. Далее компонент image получает путь до созданного гороскопа. Последняя команда показывает пользователю страницу с результатами.

    Запуск приложения

    Готовое приложение можно запустить не только при помощи специальной кнопки в IDE, но и как обычный python-скрипт. Для этого переходим в папку, в которой расположен скрипт, и открываем ее в консоли при помощи контекстного меню. Но также открыть нужную папку в консоли можно, используя команду cd:

    папка со скриптом
    Источник: автор статьи

    Далее вводим такую команду:

    python3 main.py

    В результате ее выполнения должно запуститься наше приложение. Еще один способ запуска подготовили разработчики Flet. Чтобы воспользоваться этим способом, сначала нужно установить пакет flet при помощи менеджера pip. Вводим такую команду:

    pip install flet

    И далее командуем из папки с нашим скриптом:

    flet run

    Полезные ссылки

    1. Документация фреймворка Flet.
    2. Примеры приложений на Flet.
    3. Блог Flet — новости о релизах и возможностях. 
    4. Как установить Python
    5. Подборка компиляторов для Python

    Инструменты

    Поделиться

    Скопировано
    0 комментариев
    Комментарии