Add arguments to qdarkstyle.utils entrypoint to generate custom palette assets in a specific directory

This commit is contained in:
dalthviz
2025-07-01 17:24:17 -05:00
parent ae90049e94
commit 45f0268766
4 changed files with 151 additions and 29 deletions
+7
View File
@@ -29,6 +29,8 @@ class Palette(object):
COLOR_ACCENT_4 = ''
COLOR_ACCENT_5 = ''
COLOR_DISABLED = ''
OPACITY_TOOLTIP = 0
# Size
@@ -100,3 +102,8 @@ class Palette(object):
def color_palette(cls):
"""Return the ordered colored palette dictionary."""
return cls.to_dict(colors_only=True)
@staticmethod
def from_dict(class_values, class_name="FromDictPalette"):
"""Return palette class definition from dictionary."""
return type(class_name, (Palette, ), class_values)
+65 -7
View File
@@ -5,10 +5,19 @@ Utilities for processing SASS and images from default and custom palette.
# Standard library imports
import logging
import os
import shutil
import sys
# Local imports
from qdarkstyle import PACKAGE_PATH, SVG_PATH, IMAGES_PATH
from qdarkstyle import (
PACKAGE_PATH,
SVG_PATH,
IMAGES_PATH,
MAIN_SCSS_FILE,
QSS_PATH,
STYLES_SCSS_FILE,
)
from qdarkstyle.utils.images import (
compile_qrc_file,
create_images,
@@ -39,12 +48,6 @@ def process_palette(
- QSS file in [palette_id]/[palette_id]style.qss.
- Compiled QRC file in [palette_id]/[palette_id]style_rc.py
TODO:
- Must generalize to create custom palettes and folder paths.
- Must create/copy all files under [palette_id], such as main.scss,
__init__.py, palette.py.
- Add option or avoid adding the palette under docs for custom palettes.
Args:
palette (Palette): Palette.
compile_for (list, optional): Prefix used in resources.
@@ -52,6 +55,16 @@ def process_palette(
'pyqt', 'pyqt5', 'pyqt6',
'pyside', 'pyside2', 'pyside6',
'qt', 'qt5', qt6, 'all'.
base_svg_path (str, optional): Base path for the `.svg` source files.
Defaults to `SVG_PATH`.
base_path (str): Base path for the palette directory, required for
custom palettes. Defaults to `PACKAGE_PATH`.
images_path (str): Path to save generated image files (`palette.svg` and `palette.png`).
Defaults to `IMAGES_PATH`.
resource_prefix (str, optional): Prefix used in resources.
Defaults to 'qss_icons'.
style_prefix (str, optional): Prefix used to this style.
Defaults to 'qdarkstyle'.
"""
if palette is None:
@@ -68,6 +81,50 @@ def process_palette(
id_ = palette.ID
print(f"-- PROCESSING THEME: {id_}")
# Create base palette directory and files from id
palette_path = os.path.join(base_path, id_)
if not os.path.exists(palette_path):
os.mkdir(palette_path)
init_path = os.path.join(palette_path, "__init__.py")
if not os.path.isfile(init_path):
with open(init_path, mode="x"):
pass
palette_file_path = os.path.join(palette_path, "palette.py")
if not os.path.isfile(palette_file_path):
with open(palette_file_path, mode="w") as palette_file:
palette_file.write("from qdarkstyle.palette import Palette\n\n\n")
palette_file.write(f"class {palette.__name__}(Palette):\n")
palette_file.write(f' """{palette.__name__} palette variables."""\n\n')
for attr, value in palette.to_dict().items():
if attr in ["ID", "OPACITY_TOOLTIP"]:
palette_file.write(f" {attr} = {value}\n")
else:
palette_file.write(f' {attr} = "{value}"\n')
qss_path = os.path.join(base_path, "qss")
if not os.path.exists(qss_path):
os.mkdir(qss_path)
main_scss_path = os.path.join(palette_path, MAIN_SCSS_FILE)
if not os.path.exists(main_scss_path):
# Create basic `main.scss` file for custom path
with open(main_scss_path, "w") as main_scss:
main_scss.write(f"""
/* {id_} Style - QDarkStyleSheet ------------------------------------------ */
@import '_variables';
@import '../qss/_styles';
""")
styles_scss_path = os.path.join(qss_path, STYLES_SCSS_FILE)
if not os.path.exists(styles_scss_path):
# Copy `qss/_styles.scss` file to custom path
base_styles_scss_path = os.path.join(QSS_PATH, STYLES_SCSS_FILE)
shutil.copy(base_styles_scss_path, styles_scss_path)
# TODO: delete/remove all files and folders to ensure that old files
# are not used
@@ -96,4 +153,5 @@ def process_palette(
compile_qrc_file(
compile_for=compile_for,
palette=palette,
base_path=base_path,
)
+77 -20
View File
@@ -33,6 +33,7 @@ from watchdog.observers import Observer
# Local imports
from qdarkstyle import PACKAGE_PATH, SVG_PATH, IMAGES_PATH
from qdarkstyle.palette import Palette
from qdarkstyle.dark.palette import DarkPalette
from qdarkstyle.light.palette import LightPalette
from qdarkstyle.utils import process_palette
@@ -57,30 +58,74 @@ class QSSFileHandler(FileSystemEventHandler):
print('\n')
# See https://sumit-ghosh.com/posts/parsing-dictionary-key-value-pairs-kwargs-argparse-python/
class CustomPaletteParser(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
setattr(namespace, self.dest, dict())
for value in values:
key, value = value.split('=')
getattr(namespace, self.dest)[key] = value
def main():
"""Process QRC files."""
parser = argparse.ArgumentParser(description=__doc__,
formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument('--base_path',
default=PACKAGE_PATH,
type=str,
help="Base QRC file directory.",)
parser.add_argument('--create',
default='qtpy',
choices=['pyqt5', 'pyqt6', 'pyside2', 'pyside6', 'qtpy', 'pyqtgraph', 'qt', 'qt5', 'all'],
type=str,
help="Choose which one would be generated.")
parser.add_argument('--watch', '-w',
action='store_true',
help="Watch for file changes.")
parser.add_argument('--base_svg_path',
default=SVG_PATH,
type=str,
help="Base path were source .svg files are located.",)
parser.add_argument('--images_path',
default=IMAGES_PATH,
type=str,
help="Path were documentation images are located.",)
parser.add_argument(
"--base_path",
default=PACKAGE_PATH,
type=str,
help="Base QRC file directory.",
)
parser.add_argument(
"--create",
default="qtpy",
choices=[
"pyqt5",
"pyqt6",
"pyside2",
"pyside6",
"qtpy",
"pyqtgraph",
"qt",
"qt5",
"all",
],
type=str,
help="Choose which one would be generated.",
)
parser.add_argument(
"--watch", "-w", action="store_true", help="Watch for file changes."
)
parser.add_argument(
"--base_svg_path",
default=SVG_PATH,
type=str,
help="Base path were source .svg files are located.",
)
parser.add_argument(
"--images_path",
default=IMAGES_PATH,
type=str,
help="Path were documentation images are located.",
)
parser.add_argument(
"--resource_prefix",
default="qdarkstyle",
type=str,
help="Prefix used to this style.",
)
parser.add_argument(
"--style_prefix",
default="qss_icons",
type=str,
help="Prefix used in resources.",
)
parser.add_argument(
"--custom_palette",
nargs="*",
action=CustomPaletteParser,
)
args = parser.parse_args()
@@ -95,6 +140,18 @@ def main():
except KeyboardInterrupt:
observer.stop()
observer.join()
elif args.custom_palette:
process_palette(
palette=Palette.from_dict(
args.custom_palette,
class_name=f'{args.custom_palette["ID"].capitalize()}Palette',
),
compile_for=args.create,
base_svg_path=args.base_svg_path,
images_path=args.images_path,
base_path=args.base_path,
)
else:
for palette in [DarkPalette, LightPalette]:
process_palette(
+2 -2
View File
@@ -92,7 +92,7 @@ def convert_svg_to_png(svg_path, png_path, height, width):
def create_palette_image(
base_svg_path=SVG_PATH, path=PACKAGE_PATH, palette=None
base_svg_path=SVG_PATH, path=IMAGES_PATH, palette=None
):
"""
Create palette image svg and png image on specified path.
@@ -101,7 +101,7 @@ def create_palette_image(
base_svg_path (str, optional): Base path for the `.svg` source files.
Defaults to `SVG_PATH`.
path (str): Path to save generated image files (`.svg` and `.png`).
Defaults to `PACKAGE_PATH`.
Defaults to `IMAGES_PATH`.
palette (Palette, optional): Palette.
"""
# Needed to use QPixmap