Python & EEL. Делаем просто на Python’е и красиво на JS
Вступление
Тема красивых интерфейсов была и будет актуальна всегда, кто-то использует для создания графических приложений C#, кто-то использует Java, кто-то уходит в дебри C++, ну, а кто-то извращается с Python, используя tkinter или PyQT. Существуют различные технологии, позволяющие совмещать красоту графических дизайнов, создаваемых на HTML, CSS и JS с гибкостью в реализации логики приложения, которую может дать другой язык. Так вот, для тех, кто пишет на самом лучшем языке программирования Python, есть возможность писать красивые интерфейсы на HTML, CSS и JS и прикручивать к ним логику на Python.
В этой статья я хочу показать на небольшом примере, как же все таки создать простое и красивое десктопное приложение на HTML, CSS, JS и Python. В качестве библиотеки для связи всех компонентов будем использовать EEL.
Установка
Оговорюсь, что я работаю на windows 10×64.
Для начала установим саму библиотеку выполнив простую команду: pip install eel
После установки одной лишь библиотеки можно начинать наш путь.
Наше приложение будет выглядеть таким образом:
Логика приложения очень простая: при нажатии кнопки «рассчитать» считываются значения в поле для ввода рублей, полученные данные отправляются в Python, где происходит расчет курса валют. Python возвращает нам данные и мы выводим из через JS
Раскидываем по папкам
Разобьем теперь наш проект на модули. В папку «front» будем класть всё, что связано с графической частью нашего приложения. В папку «back» будем помещать все наши исходники на python. Еще создадим папку middle, в которую будем помещать методы, вызываемые из JS (об этом чуть позже). В Главной директории создадим файл main.py, он будет запускать наше приложение.
Логика на Python
В качестве теста реализуем простое приложение конвертер валют (да-да, банально, никому не надо, на гитхабе миллион проектов). Для этого на python установим библиотеку CurrencyConverter: pip install currencyconverter
Теперь приступим к написанию логики на python. Реализуем метод, который на вход будет принимать сумму, валюту с которой нам надо перевести и валюту, на которую нам надо перевести. Создадим «convert.py» в директории «back» и запишем в него следующий код:
from currency_converter import CurrencyConverter
converter = CurrencyConverter()
def convert_value(value: float, from_cur: str, to_cur: str):
return converter.convert(value, from_cur, to_cur)
Теперь в директории «middle» создадим файл «mid_convert.py» и пропишем следующий код:
from back.convert import convert_value
import eel
@eel.expose
def convert_value_py(value:float, from_cur:str, to_cur:str)->float:
return convert_value(value, from_cur, to_cur)
Что здесь вообще происходит? Файл «mid_convert.py» будет служит связующим звеном между JS и Python. Декоратор @eel.expose дает нашей программе понять, что функция, описанная ниже, может быть вызвана из JS. Таким образом, любая функция, которую мы в будущем захотим вызывать из JS, должна быть обернута декоратором @eel.expose. Очевидно, что не имеет смысла делать лишних модулей, если у вас простой проект, можно было обернуть декоратором функцию «convert_value» в модуле «convert.py». В больших проектах разбиение программы на такие слои позволит легче расширять и оптимизировать код.
Подключаем Python к JS
Теперь подключим нашу логику на Python к самому JS. Для этого примера я использую простую страничку, сверстанную чисто при помощи HTML, CSS (но вы можете подключить к своей страничке vue.js, react.js и другие популярные фреймворки, которые нужны вам для работы с графикой). Первым делом необходимо подключить библиотеку eel к самому JS:
Далее реализуем функционал кнопки «рассчитать». По нажатию кнопки первым делом необходимо считать значение рублей и пойти по каждой валюте, чтобы перевести значение.
async function create_cur_for_rub (){
// получаем значение введенных рублей
let value_rub = parseFloat(document.getElementById("rub-input").value);
// получаем список всех input'ов, в которые надо перевести рубли
let list_curs = document.getElementById("list-cur").children;
for (let div_cur of list_curs) {
// берем название денежной единицы
let name_cur = div_cur.getElementsByTagName("span")[0].textContent;
// теперь передает значение в Python для обработки
let value_cur = await eel.convert_value_py(value_rub, "RUB", name_cur)();
// выводим на экран полученное значение
div_cur.getElementsByTagName("input")[0].value = value_cur;
}
}
document.getElementById("btn-sum").onclick = create_cur_for_rub;
Обратите внимание на строку «let value_cur = await eel.convert_value_py (value_rub, «RUB», name_cur)();». Важно, что вызов функции из питона происходит в асинхронном режиме, поэтому обязательно необходимо сделать асинхронной ту функцию, в которой есть вызов Python кода. При вызове функции из eel необходимо ставить пару (), где в первые круглые скобки будут передаваться наши аргументы.
Проверим, работает ли.
Как мы видим, все работает.
Запуск программы
Для запуска кода используем файл «main.py». В нем импортируем библиотеку eel и всё, что мы писали в файле «min_convert.py» для того, чтобы при запуске проекта подтянуть все функции, которые мы оборачивали в eel.expose:
import eel
from middle.mid_convert import *
Теперь необходимо проинициализировать через eel ту директорию, где лежит front-end нашего приложения. При помощи команды eel.init (args). Далее для запуска самого приложения вызывает метод eel.start (args):
if __name__ == '__main__':
eel.init('front')
eel.start('index.html', mode="chrome", size=(760, 760))
Метод eel.start принимает на вход несколько параметров (подробнее о них см. официальную документацию по eel). Самым интересным параметром является «mode». При помощи него вы можете запустить свой проект, как в браузере, так и в виде отдельного приложения. Например, вы можете указать параметр «default», в таком случае приложению будет запускать в браузере по умолчанию. Если у вас стоит google chrome, то указав параметр «mode=chrome» ваша программа откроется в виде отдельного приложения.
Также можно использовать chromium. Для этого скачиваем его с официального сайта. Разархивируем его в какую-нибудь папку и прописываем следующий код в нашем «main.py»:
eel.browsers.set_path("chrome", "C:/Users/admin/Documents/chrome-win/chrome.exe")
eel.start('index.html', mode="chrome", size=(760, 760))
Вывод
Как мы видим, то создавать красивые десктопные приложения с использованием Python в качестве языка для реализации основной логики не так сложно. Вы можете устанавливать какие угодно библиотеки, реализовать нужный код с использованием Python, а писать красивые интерфейсы на HTML, CSS и JS.
Ссылка на проект github
P.S. это моя первая статья на Habr, пишите Ваши пожелания, замечания и отзывы, буду рад увидеть любой комментарий.