Расскажем, что такое 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:
Запускаем этот скрипт как приложение. При помощи клика правой кнопкой мыши вызываем контекстное меню и в нем выбираем пункт «Запустить как приложение». После принятия лицензионного соглашения перед нами должно появиться стартовое окно среды:
Для того чтобы значок IDE отображался в меню приложений, следует нажать на символ шестеренки в нижнем левом углу и в открывшемся списке выбрать пункт «Create Desktop Entry…».
Создание проекта
Нажимаем на «New Project» и в появившемся окне вводим название проекта (zodiac), выбираем месторасположение проекта, а также отмечаем правый чекбокс, чтобы среда создала для нас приветственный скрипт. Все остальные настройки оставляем как есть:
Теперь можно смело жать на кнопку «Create». После открытия проекта нажимаем на зеленый треугольник в верхней части окна. Запустится приветственный скрипт:
Мы проверили, что все работает как надо. Теперь эти строки можно удалить. Нам они больше не понадобятся. Вместо них следует ввести:
def main(page: Page): pass app(main)
Это базовая структура приложения. На месте ключевого слова pass будет находиться весь код приложения. Для начала можно создать заголовок окна:
def main(page: Page): page.title = "Zodiac" app(main)
Теперь поговорим об интерфейсе приложения.
Интерфейс приложения
Приложение состоит из двух страниц. На первой странице пользователь вводит данные, а на второй — получает результат. Для вычислений приложение использует библиотеку Kerykeion. Гороскоп получается в формате векторного изображения (SVG). Дополнительно выводится сводная таблица гороскопа. Первая страница приложения имеет такой вид:
Вторая страница:
Исходный код приложения можно посмотреть здесь.
Отображение страниц
Для отображения страниц применяется такая функция:
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 — это сообщение, которое всплывает в нижней части окна и через несколько секунд исчезает. Выглядит оно примерно так:
Для того чтобы использовать все перечисленные компоненты, в самом начале исходника необходимо произвести соответствующий импорт:
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
Полезные ссылки
- Документация фреймворка Flet.
- Примеры приложений на Flet.
- Блог Flet — новости о релизах и возможностях.
- Как установить Python
- Подборка компиляторов для Python