Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can this be used for regular Qt applications built in C++? #25

Open
GavinNL opened this issue Apr 22, 2021 · 19 comments
Open

Can this be used for regular Qt applications built in C++? #25

GavinNL opened this issue Apr 22, 2021 · 19 comments

Comments

@GavinNL
Copy link

GavinNL commented Apr 22, 2021

If so, how can this be achieved? I tried using the template file as a qss, but it didn't seem to work.

@YeisonCardona
Copy link
Contributor

Hi @GavinNL,

Are you using the material.css.template as it or after rendering?

@GavinNL
Copy link
Author

GavinNL commented Apr 23, 2021

I'm not quite familiar with how to use the .templates. I've only ever used the .qss file. I renamed the .template to .qss and tried to import it using the standard method

	//create the application and the main window
	QApplication app(argc, argv);
	MainWindow w;

	//open qss file
	QFile file("material.qss");
	file.open(QFile::ReadOnly);

	QString styleSheet { file.readAll() };

@GavinNL
Copy link
Author

GavinNL commented Apr 23, 2021

I assume you need a generate a .qss file somehow before it can be used within Qt as a stylesheet?

@YeisonCardona
Copy link
Contributor

Try with this file dark_teal.txt (as .qss), if it works, the colors and widgets must change, but with missing icons.

@GavinNL
Copy link
Author

GavinNL commented Apr 23, 2021

Okay that worked! Thanks

I found the build_stylesheet() function, I managed to get it to build the qss sheet.

#!/usr/bin/python3
import sys
from PySide2 import QtWidgets

from qt_material import build_stylesheet

# create the application and the main window
app = QtWidgets.QApplication(sys.argv)

print( build_stylesheet(theme='light_blue.xml') )

I believe you can embed base64 images right into the stylesheet (https://forum.qt.io/topic/89128/qt-stylesheet-image-can-i-add-svg-code-in-image-instead-of-specifying-url/2 )

I think a really useful feature would be a command line function to generate the qss files with embedded images. That way people can use your themes outside of pyside.

python3 -m qt_material.buildqss "light_blue.xml" > output.qss

@YeisonCardona
Copy link
Contributor

I was trying with data:image/svg+xml instead of base64 because I have SVG images, but I can not view them.
The template assumes that there is an icon:/ path, I'm adding this path with QDir.addSearchPath('icon', 'theme')

Can you please try this in C++, with this theme.zip generated theme folder as SearchPath.

Now you could see the theme and icons, or not.

@GavinNL
Copy link
Author

GavinNL commented Apr 23, 2021

I added this line to my C++ code, and placed the "theme" folder in the same directory as my executable.
I don't think the icons showed up.

QDir::addSearchPath("icon", "./theme");

In the qss file, I noticed

QSpinBox::down-button:disabled {
  image: url(:/icon/disabled/downarrow.svg);
}

So i tired setting the folder structure as:

theme
+ -- icon
      +--disabled
      +--primary

But that didn't work either

@GavinNL
Copy link
Author

GavinNL commented Apr 23, 2021

I think I managed to get it to work...but I had to do the following

I had to modify the .qss file and replace all instances of url(:/icon/XXXXXX) with url(icon/XXXXX)

Then i had to have my folder structure looking like this:

executable
icon
+--primary
+--disabled

Then it was able to find the files properly

@GavinNL
Copy link
Author

GavinNL commented Apr 23, 2021

Okay more success.

In my C++ code I added this:

QDir::addSearchPath("icon", QDir::currentPath() + "/theme");

Then I had to modify all the urls to look something like this:

url(icon:/disabled/downarrow.svg")

Then it started working and I could see the various icons.

@YeisonCardona
Copy link
Contributor

At this point, I can add a method to generate the qss and the icons folder for a specific theme and let the users add it to their code.

@GavinNL
Copy link
Author

GavinNL commented Apr 23, 2021

That would be awesome!

@YeisonCardona
Copy link
Contributor

Ok
In the last commit, you can do:

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,)

or

from qt_material import export_theme

export_theme(theme='dark_teal.xml', qss='dark_teal.qss', output='theme', prefix='icon:/')

With the same documented arguments for apply_stylesheet and new ones:

  • qss: The .qss filename
  • output: The folder path (absolute or relative) for the SVG resources
  • prefix: The prefix used on the QSS file ('icon:/' by default).

So, try it and tell me how works for you, or if there are needed more options.

@GavinNL
Copy link
Author

GavinNL commented Apr 23, 2021

Looks like its working! Thanks for the quick turn around on this!

@akshaybabloo
Copy link

@GavinNL Do you mind sharing your code on how you were able to set the SVG icons without using a qrc file?

@GavinNL
Copy link
Author

GavinNL commented May 8, 2021

Hi @akshaybabloo , you can do this relatively easily in 2 steps.

  1. Generate the qss and icon files. I do this directly from my bash terminal. Type in each line individually
git clone https://github.com/UN-GCPDS/qt-material.git
cd qt-material
python3

While in the python terminal, run the following

from qt_material import export_theme
export_theme(theme='dark_teal.xml', qss='dark_teal.qss', output='theme', prefix='icon:/')
exit()

This will create a file dark_teal.qss and a folder, theme.

  1. Copy these two folders to where your Qt C++ binary is.

In your C++ code, add the following right after you create your QApplication

  QApplication app(argc, argv);

  {
     // must give an absolute path to the "theme" folder
      QDir::addSearchPath("icon", QDir::currentPath() + "/theme");
      
          QFile file("dark_teal.qss");
          file.open(QFile::ReadOnly);

          QString styleSheet { file.readAll() };
          app.setStyleSheet(styleSheet);
  }

Hopefully this helps

@YeisonCardona YeisonCardona reopened this May 9, 2021
@akshaybabloo
Copy link

@GavinNL I tried it, but I still get file not found. Creating a qrc file fixed it. See #28.

@GavinNL
Copy link
Author

GavinNL commented May 9, 2021

@akshaybabloo , did you properly load the qss file from the correct location?

Edit the .qss file and make sure all the paths to the icons look correct, they should look something like this:

  image: url(icon:/disabled/downarrow.svg);

Make sure that the qss file and the theme folder that was generated are in the same folder as your binary file. You can change this, but then you'll have to update the paths in the sample code I gave you.

@martinrotter
Copy link

I get segfaults when trying to produce QSS.

>>> 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,)
Segmentation fault

@YeisonCardona YeisonCardona reopened this Nov 5, 2021
@pstavirs
Copy link

pstavirs commented Dec 18, 2021

  • Needs Python 3.7+ - although setup.py has python_requires set correctly, I was using pip 8.1.1 which doesn't recognize this constraint. Would be good to mention in README.md
  • On Python for Windows with PyQt5 it crashes due to https://bugreports.qt.io/browse/PYSIDE-156 - Fix is to create a PyQt5.QApplication first
import sys
import PyQt5
from qt_material import export_theme

extra = {
}

app = PyQt5.QtWidgets.QApplication(sys.argv)

export_theme(theme='dark_amber.xml', qss='dark_amber.qss', output='dark_amber_icons',
                       prefix='icon:/', invert_secondary=False, extra=extra,)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants