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
После установки одной лишь библиотеки можно начинать наш путь.

Наше приложение будет выглядеть таким образом:

c4d8aea182604288e95f486f394d6f6e.PNG


Логика приложения очень простая: при нажатии кнопки «рассчитать» считываются значения в поле для ввода рублей, полученные данные отправляются в Python, где происходит расчет курса валют. Python возвращает нам данные и мы выводим из через JS

Раскидываем по папкам

Разобьем теперь наш проект на модули. В папку «front» будем класть всё, что связано с графической частью нашего приложения. В папку «back» будем помещать все наши исходники на python. Еще создадим папку middle, в которую будем помещать методы, вызываемые из JS (об этом чуть позже). В Главной директории создадим файл main.py, он будет запускать наше приложение.

3c062ed07aad776547493ea7aa90177d.PNG

Логика на 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 необходимо ставить пару (), где в первые круглые скобки будут передаваться наши аргументы.

Проверим, работает ли.

565d8f9b2f630fdffc3fc399150a3c7a.PNG

Как мы видим, все работает.

Запуск программы

Для запуска кода используем файл «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, пишите Ваши пожелания, замечания и отзывы, буду рад увидеть любой комментарий.

© Habrahabr.ru