UN-GCPDS / qt-material

Material inspired stylesheet for PySide2, PySide6, PyQt5 and PyQt6
https://qt-material.readthedocs.io/en/latest/
BSD 2-Clause "Simplified" License
2.4k stars 254 forks source link

Using the exporter with rcc file doesn't work #48

Open pstavirs opened 2 years ago

pstavirs commented 2 years ago

With the default values of prefix='icon:/' and output='theme' in export_theme(),

When the RCC file is loaded in Qt/C++ app and stylesheet applied, the QSS looks for the icons at filesystem path - <cwd>/<url-in-qss>, where cwd is the current working directory. It should look in the loaded resources not the filesystem.

I think only when the path has : at the start, does Qt look into resources. The resource prefix I think comes after the :. But, I could be wrong. The Qt Resources documentation is not very clear.

pstavirs commented 2 years ago

Here's a patch that fixes this -

diff --git a/qt_material/__init__.py b/qt_material/__init__.py
index e6ac03c..6215e08 100644
--- a/qt_material/__init__.py
+++ b/qt_material/__init__.py
@@ -42,7 +42,7 @@ template = 'material.css.template'

 # ----------------------------------------------------------------------
-def export_theme(theme='', qss=None, rcc=None, invert_secondary=False, extra={}, output='theme', prefix='icon:/'):
+def export_theme(theme='', qss=None, rcc=None, invert_secondary=False, extra={}, output='icons', prefix=':/theme'):
     """"""
     if not os.path.isabs(output) and not output.startswith('.'):
             output = f'.{output}'
@@ -50,17 +50,17 @@ def export_theme(theme='', qss=None, rcc=None, invert_secondary=False, extra={},
     stylesheet = build_stylesheet(
         theme, invert_secondary, extra, output)

+    if output.startswith('.'):
+        output = output[1:]
+
     with open(qss, 'w') as file:
-        file.writelines(stylesheet.replace('icon:/', prefix))
+        file.writelines(stylesheet.replace('icon:/', f'{prefix}/{output}/'))

     if rcc:

         with open(rcc, 'w') as file:
             file.write('<RCC>\n')
-            file.write(f'  <qresource prefix="{prefix[:-2]}">\n')
-
-            if output.startswith('.'):
-                output = output[1:]
+            file.write(f'  <qresource prefix="{prefix[2:]}">\n')

             for subfolder in ['disabled', 'primary']:
                 files = os.listdir(os.path.join(

This patch changes default values of prefix and output and the result is that

YeisonCardona commented 2 years ago

Hi

These changes will not work for me.

I really need icon:/ as prefix and the paths in the .qss file must looks like url(icon:/primary/close.svg); Then I can use addSearchPath to configure my system with the icon prefix and an absolute path. Then I can load my icons (in Qt) with QIcon("icon:/primary/close.svg")

I really can't test this out of Python.

pstavirs commented 2 years ago

@YeisonCardona My changes are restricted to the export_theme() function - which I believe is not called or used when applying the stylesheet with PyQt/PySide. Or am I missing something?

Thank you for all your work on this theme.

YeisonCardona commented 2 years ago

(I'm totally sure about responding to this previously, but I can't find my answer)

You are right, export_theme is not used at runtime. But the structure of the files must be valid for all Qt environs.

You are testing without addSearchPath call? Are you loading the files just from local or absolute paths? Your method don't need prefix?

pstavirs commented 2 years ago

Here's my code that loads the qss and rcc file. I don't use any prefixes.

    QFile qssFile(themeDir_ + theme + ".qss");
    if (!qssFile.open(QFile::ReadOnly)) {
        qDebug("Unable to open theme qssFile %s",
               qPrintable(qssFile.fileName()));
        return;
    }

    // Register theme resource before applying theme style sheet
    QString rccFile = themeDir_ + theme + ".rcc";
    if (!QResource::registerResource(rccFile))
        qDebug("Unable to register theme rccFile %s", qPrintable(rccFile));

    QString styleSheet { qssFile.readAll() };
    qApp->setStyleSheet(styleSheet);

PS - I'm using a separate QSS file rather than the one in the RCC so that I can experiment by changing the QSS at run time during development