Шаблонизатор html для метода .setHtml() pyqt

131
09 декабря 2019, 18:00

Использую pyqt в своем приложении и столкнулся с вопросом хранения/генерирования html кода. На скриншоте снизу показано как я сейчас генерирую код, затем передаю это значение в метод .setHtml(), но хранить в таком виде мне бы не хотелось. Есть ли возможность подключить шаблонизатор по типу twig или аналога для управления, и не будет ли это сильно накладно по ресурсам? Может проще будет самому что-то подобное реализовать?

Answer 1

Подключил очень простой шаблонизатор. ссылка на статью http://alexmic.net/building-a-template-engine/ ссылка на гит https://github.com/alexmic/microtemplates/

В коде надо сделать небольшую правку. 1) Для питона 3.х нужно поправить эксепшены(нужно взять в скобки) Находим в файле base.py:

except ValueError, IndexError:

и заменяем на:

except (ValueError, IndexError):

2) В шаблонизатор можно передавать переменные и словари. При попытке отправить dataclass поймал ошибку. Нужно в файле base.py найти строку:

context = context[tok]

и заменить на это:

if isinstance(context, dict):
    context = context[tok]
else:
    context = getattr(context, f'{tok}')

И еще исправить баг. Найти строку:

if_branch, else_branch = self.split_children()

заменить на:

self.if_branch, self.else_branch = self.split_children()

Подключил все это дело я таким способом:

context = {
    'out': outputs,
    'in_unspent': inputs,
}
input_html = util.read_html('input_list')
output_html = util.read_html('output_list')
render_html_in = util.minitemplates.Template(input_html).render(**context)
render_html_out = util.minitemplates.Template(output_html).render(**context)

Причем input и output являются списком объектов dataclass.

А вот так выглядит функция read_html:

TEMPLATE_DIR = os.path.join(os.path.dirname(__file__), '..\\resource\\templates')

def read_html(engine, template_dir=TEMPLATE_DIR):
    html_file_path = os.path.join(template_dir, "%s.html" % engine)
    with open(html_file_path) as html_file:
        html = html_file.read()
    return html

Модуль очень простой и легкий. Для простых задач в методе .setHtml() вполне достаточно!

По производительности вот тесты:

microtemplates => run 10000 times, took 0.36 ms
django => run 10000 times, took 0.95 ms
django_default_loader => run 10000 times, took 1.16 ms
django_cached_loader => run 10000 times, took 0.46 ms
jinja2 => run 10000 times, took 5.64 ms
jinja2_env => run 10000 times, took 0.08 ms

UPD:

Дополнение - нашел баг в шаблонизаторе с выводом числа '0'. Если попробовать вывести в цикле переменную с 0, то на его месте будет пустой стринг.

Фиксится просто. В base.py найти 128 строку:

 return '' if not child_html else str(child_html)

и заменить на это:

 return '' if not str(child_html) else str(child_html)
READ ALSO
Почему ломается вёрстка в данном случае?

Почему ломается вёрстка в данном случае?

Разбираюсь в примере адаптивной вёрстки с w3schoolsИ не могу понять, почему, когда я убираю вроде необязательный кусок кода, ломается вся вёрстка

112
Шрифты. Поддержка немецкого языка

Шрифты. Поддержка немецкого языка

Как проверить, поддерживает ли шрифт немецкий язык? Допустим в google fonts, нужно ли как-то дополнительно настраивать, чтобы шрифт поддерживал...

108
Использовать проверку полей в форме без отправки данных и выводом на печать

Использовать проверку полей в форме без отправки данных и выводом на печать

Нужна проверка input без отправки формы на сервер с дальнейшим выполнением действийКороче говоря, хотел пойти простым путем)) и использовать...

114
Узнать находятся ли элементы на одном листе при печати

Узнать находятся ли элементы на одном листе при печати

с помощью wkhtmltopdf я формирую pdf файл, который содержит таблицу, а после блок со служебной инфойМне необходимо, что если несколько листов в документе,...

125