From f42747d54fd1aea75270e90a115782b563a6f241 Mon Sep 17 00:00:00 2001 From: Yeison Date: Fri, 23 Apr 2021 17:51:27 -0500 Subject: [PATCH] Added exporter feature --- examples/exporter/exporter.py | 21 ++++++++++++++ examples/runtime/extra.py | 4 ++- qt_material/__init__.py | 46 +++++++++++++++++++++---------- qt_material/resources/__init__.py | 2 +- qt_material/resources/generate.py | 23 +++++++++++----- 5 files changed, 73 insertions(+), 23 deletions(-) create mode 100644 examples/exporter/exporter.py diff --git a/examples/exporter/exporter.py b/examples/exporter/exporter.py new file mode 100644 index 0000000..da48e8d --- /dev/null +++ b/examples/exporter/exporter.py @@ -0,0 +1,21 @@ +from qt_material import export_theme + +extra = { + + # Button colors + 'danger': '#dc3545', + 'warning': '#ffc107', + 'success': '#17a2b8', + + # Font + 'font_family': 'monoespace', + 'font_size': '14px', + 'line_height': '14px', +} + + +export_theme(theme='dark_teal.xml', qss='dark_teal.qss', output='theme', prefix='icon:/', + invert_secondary=False, extra=extra,) + + + diff --git a/examples/runtime/extra.py b/examples/runtime/extra.py index 6aa6af4..a268344 100644 --- a/examples/runtime/extra.py +++ b/examples/runtime/extra.py @@ -11,7 +11,9 @@ extra = { 'success': '#17a2b8', # Font - 'font_family': 'mono', + 'font_family': 'monoespace', + 'font_size': 'mono', + 'line_height': '14px', } diff --git a/qt_material/__init__.py b/qt_material/__init__.py index c4af45b..6fd9e5e 100644 --- a/qt_material/__init__.py +++ b/qt_material/__init__.py @@ -1,9 +1,11 @@ import os import sys import logging +import base64 from xml.etree import ElementTree -from qt_material.resources import ResourseGenerator +from qt_material.resources import ResourseGenerator, RESOURCES_PATH +GUI = True if 'PySide2' in sys.modules: from PySide2.QtGui import QFontDatabase, QColor, QGuiApplication, QPalette @@ -29,6 +31,7 @@ elif 'PyQt6' in sys.modules: from PyQt5.QtCore import Qt, QDir from PyQt5 import uic else: + GUI = False logging.warning("qt_material must be imported after PySide or PyQt!") import jinja2 @@ -37,7 +40,20 @@ template = 'material.css.template' # ---------------------------------------------------------------------- -def build_stylesheet(theme='', invert_secondary=False, resources=[], extra={}, parent='theme'): +def export_theme(theme='', qss=None, invert_secondary=False, extra={}, output='theme', prefix='icon:/'): + """""" + if not os.path.isabs(output) and not output.startswith('.'): + output = f'.{output}' + + stylesheet = build_stylesheet( + theme, invert_secondary, extra, output) + + with open(qss, 'w') as file: + file.writelines(stylesheet.replace('icon:/', prefix)) + + +# ---------------------------------------------------------------------- +def build_stylesheet(theme='', invert_secondary=False, extra={}, parent='theme'): """""" theme = get_theme(theme, invert_secondary) if theme is None: @@ -47,11 +63,12 @@ def build_stylesheet(theme='', invert_secondary=False, resources=[], extra={}, p loader = jinja2.FileSystemLoader(os.path.join( os.path.dirname(os.path.abspath(__file__)))) - env = jinja2.Environment(autoescape=True, loader=loader) + env = jinja2.Environment(autoescape=False, loader=loader) theme['icon'] = None env.filters['opacity'] = opacity + # env.filters['as_base64'] = as_base64 # env.filters['load'] = load stylesheet = env.get_template(template) @@ -63,10 +80,11 @@ def build_stylesheet(theme='', invert_secondary=False, resources=[], extra={}, p theme.update(extra) - default_palette = QGuiApplication.palette() - default_palette.setColor(QPalette.PlaceholderText, QColor( - *[int(theme['primaryColor'][i:i + 2], 16) for i in range(1, 6, 2)] + [92])) - QGuiApplication.setPalette(default_palette) + if GUI: + default_palette = QGuiApplication.palette() + default_palette.setColor(QPalette.PlaceholderText, QColor( + *[int(theme['primaryColor'][i:i + 2], 16) for i in range(1, 6, 2)] + [92])) + QGuiApplication.setPalette(default_palette) return stylesheet.render(**theme) @@ -125,10 +143,8 @@ def add_fonts(): # ---------------------------------------------------------------------- -def apply_stylesheet(app, theme='', style=None, save_as=None, invert_secondary=False, resources=[], extra={}, parent='theme'): +def apply_stylesheet(app, theme='', style=None, save_as=None, invert_secondary=False, extra={}, parent='theme'): """""" - add_fonts() - if style: try: app.setStyle(style) @@ -136,7 +152,7 @@ def apply_stylesheet(app, theme='', style=None, save_as=None, invert_secondary=F logging.error(f"The style '{style}' does not exist.") pass stylesheet = build_stylesheet( - theme, invert_secondary, resources, extra, parent) + theme, invert_secondary, extra, parent) if stylesheet is None: return @@ -163,9 +179,11 @@ def set_icons_theme(theme, parent='theme'): resources = ResourseGenerator(primary=theme['primaryColor'], secondary=theme['secondaryColor'], disabled=theme['secondaryLightColor'], source=source, parent=parent) resources.generate() - QDir.addSearchPath('icon', resources.index) - QDir.addSearchPath('qt_material', os.path.join( - os.path.dirname(__file__), 'resources')) + + if GUI: + QDir.addSearchPath('icon', resources.index) + QDir.addSearchPath('qt_material', os.path.join( + os.path.dirname(__file__), 'resources')) # ---------------------------------------------------------------------- diff --git a/qt_material/resources/__init__.py b/qt_material/resources/__init__.py index fd5a15f..623e58a 100644 --- a/qt_material/resources/__init__.py +++ b/qt_material/resources/__init__.py @@ -1 +1 @@ -from .generate import ResourseGenerator +from .generate import ResourseGenerator, RESOURCES_PATH diff --git a/qt_material/resources/generate.py b/qt_material/resources/generate.py index 68b84f7..e4b25cb 100644 --- a/qt_material/resources/generate.py +++ b/qt_material/resources/generate.py @@ -14,9 +14,16 @@ class ResourseGenerator: def __init__(self, primary, secondary, disabled, source, parent='theme'): """Constructor""" + if parent.startswith('/'): + self.index = parent + if parent.startswith('.'): + self.index = parent[1:] + else: + self.index = os.path.join(RESOURCES_PATH, parent) + self.contex = [ - (os.path.join(RESOURCES_PATH, parent, 'disabled'), disabled), - (os.path.join(RESOURCES_PATH, parent, 'primary'), primary), + (os.path.join(self.index, 'disabled'), disabled), + (os.path.join(self.index, 'primary'), primary), ] self.source = source @@ -26,9 +33,8 @@ class ResourseGenerator: shutil.rmtree(folder, ignore_errors=True) os.makedirs(folder, exist_ok=True) - self.index = os.path.join(RESOURCES_PATH, parent) - # ---------------------------------------------------------------------- + def generate(self): """""" for icon in os.listdir(self.source): @@ -40,7 +46,8 @@ class ResourseGenerator: for folder, color in self.contex: new_content = self.replace_color(content_original, color) - new_content = self.replace_color(new_content, self.secondary, '#ff0000') + new_content = self.replace_color( + new_content, self.secondary, '#ff0000') file_to_write = os.path.join(folder, icon) with open(file_to_write, 'w') as file_output: @@ -49,13 +56,15 @@ class ResourseGenerator: # ---------------------------------------------------------------------- def replace_color(self, content, replace, color='#0000ff'): """""" - colors = [color] + [''.join(list(color)[:i] + ['\\\n'] + list(color)[i:]) for i in range(1, 7)] + colors = [color] + [''.join(list(color)[:i] + + ['\\\n'] + list(color)[i:]) for i in range(1, 7)] for c in colors: content = content.replace(c, replace) replace = '#ffffff00' color = '#000000' - colors = [color] + [''.join(list(color)[:i] + ['\\\n'] + list(color)[i:]) for i in range(1, 7)] + colors = [color] + [''.join(list(color)[:i] + + ['\\\n'] + list(color)[i:]) for i in range(1, 7)] for c in colors: content = content.replace(c, replace)