从Qt资源系统加载Jinja2模板

2024-05-01 21:52:48 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试从Qt资源系统加载一些Jinja2模板。我使用的是Python 3.8.3、Jinja 2.11.2和PyQt 5.15

问题是,我甚至无法检测加载模板的qrc路径。QRC仅适用于Qt类

Python代码:

from jinja2 import Environment, FileSystemLoader

file_loader = FileSystemLoader(":/plantillas/")  # Here is my problem, how I should detect the qrc path?
env = Environment(loader=file_loader)
plantilla = env.get_template("base.md")

qrc:

<!DOCTYPE RCC>
<RCC version="1.0">
    <qresource prefix="plantillas">
        <file alias="base.md">plantillas/base.md</file>
    </qresource>
</RCC>

Tags: env模板baseenvironment系统资源loaderqt
1条回答
网友
1楼 · 发布于 2024-05-01 21:52:48

QResource只在Qt世界中工作,因此一个可能的解决方案是使用Qt类创建加载程序:

qloader.py

import os
from collections import abc

from jinja2.loaders import BaseLoader, split_template_path
from jinja2.exceptions import TemplateNotFound

from PyQt5.QtCore import QDir, QDirIterator, QFile, QFileInfo, QIODevice


class QFileSystemLoader(BaseLoader):
    def __init__(self, searchpath, encoding="utf-8", followlinks=False):
        if not isinstance(searchpath, abc.Iterable) or isinstance(searchpath, str):
            searchpath = [searchpath]

        self.searchpath = list(searchpath)
        self.encoding = encoding
        self.followlinks = followlinks

    def get_source(self, environment, template):
        pieces = split_template_path(template)
        for searchpath in self.searchpath:
            filename = os.path.join(searchpath, *pieces)

            f = QFile(filename)
            if not f.exists():
                continue
            if not f.open(QIODevice.ReadOnly):
                continue
            contents = f.readAll().data().decode(self.encoding)
            f.close()

            dt = QFileInfo(f).fileTime(QFile.FileModificationTime)

            def uptodate():
                return QFileInfo(filename).fileTime(QFile.FileModificationTime) == dt

            return contents, filename, uptodate
        raise TemplateNotFound(template)

    def list_templates(self):
        found = set()
        for searchpath in self.searchpath:
            d = QDir(searchpath)
            it_flag = QDirIterator.Subdirectories
            if self.followlinks:
                it_flag |= QDirIterator.FollowSymlinks
            it_filter = QDir.Files | QDir.NoDotAndDotDot | QDir.Hidden | QDir.Readable
            if not self.followlinks:
                it_filter |= QDir.NoSymLinks
            it = QDirIterator(searchpath, it_filter, it_flag)
            while it.hasNext():
                it.next()
                found.add(d.relativeFilePath(it.filePath()))
        return sorted(found)
from qloader import QFileSystemLoader


qfile_loader = QFileSystemLoader(":/plantillas/")
env = Environment(loader=qfile_loader)
plantilla = env.get_template("base.md")

相关问题 更多 >