is Theme and OS detectable to python?

Well today I was on Linux and saw how hideous my add-on is there which left me thinking.

Is it possible to ask/detect the currently used Krita Theme (or set of colors being used in the active theme) and the OS the addon is running on?
kindda like you do to know the krita version.

I can make icons but they will always suffer of the issue of being too dark in the dark theme or just too white in the light theme. Knowing the theme or color being used you can calibrate them to be visible and within theme colors.

And knowing the OS where it was running I can use a different UI on run time so things line up properly. this because Linux and windows pixel size and font size are different in PyQt5. Don’t ask my why I just see it happen.

Hi

Yes, it’s possible… but not easy for my own experience.
I don’t know if the way I’ve implemented it is the best or not.
Maybe a simpler method exists, I don’t know, but it works.

In BuliCommander plugin, I need to load icon set according to theme (dark or light) and solution I found is to check current window background color defined by Qt.

Take a look on BCTheme class.
It detect if current theme is Dark or Light, and allow to return a dictionary of stylesheet according to current theme.

Concerning resources (icons), it’s more tricky.

You need to prepare resource files:

  1. Create SVG files for dark/black
  2. Use the QtDesigner to generate resource file (.qrc), one for Dark theme, on for Light theme (or build it manually if you prefer, QRC file is just an XML file)
  3. Convert the .qcc file to .rcc file (use Qt rcc command line tool)

So now, you have resource files, you need to load them…
The loadResources() method from the BCTheme does it.

Not yet implemented in my plugin, but I need to detect when the theme is changed to reload resource dynamically (currently, theme is properly applied only when plugin is initialised and if theme is modified in Krita, user have to restart Krita to have theme properly applied in plugin)
The signal void Window::themeChanged() might be helpfull for this.

For OS detection, I use sys.platform value, but I think there’s many other way to do it…

Grum999

1 Like

For the OS, use https://doc.qt.io/qt-5/qsysinfo.html. For icons, there is already a system in place that loads the light or dark icons depending on the theme, but for that icons must be in a place where where Qt’s icon loader finds them. Krita puts its own icons in a qrc file, but the icon loader should still be able to find icons if they are in the correct location.

with the OS thing I ended up doing:

  • Optimizations that should be intended for Linux but I might keep them for Windows just to keep consistent behavior perhaps unless I get upset with it for some reason.
  • The icon set
  • Did a new UI. initially I wanted to make it for Linux but Windows had a update recently and I hard to do a format because the update did not work smoothly. The result was that Windows scaling is much different now. I have not tested it yet but I think the new UI might work for Linux users too.

Also was around fixing bugs mostly I have alot of ideas that I write down and then never end up using or just become obsolete because another functions needs something different entirely. so bug fixing and taking out the trash.

Considering the icons I was planning to embed them into the code as I have been doing up till now.
I make the SVG file in Inkscape per example and then I see the SVG code clean it up and create a small string out of it and then I load it up into the Code. since it is a function inside the code i can send in a hex code and change the color set of it as needed.

SVG loaded icon arrows
the loading code

like this I would be able to change the icon color to an accent color (blue once it was active) or back to whitish of blackish considering it being inactive and the theme selected. I just need to know the theme active and the accent color to make it blend in smoothly but if i know just light and dark I can still make it work. once i make all the SVGs in code I will make the detecting with your pointers @Grum999

@Grum999
I was checking it better now and the code is pretty good. it does give a very good indicator to infer a decision on the current themes tone.

However since I am working on a docker it gives a error message. Only when I changed to check the code in the scripter was i able to verify it was working properly. Maybe because the docker is loaded in a bad order for it to make that question? donno, but in broad terms with the accent color in the icon seems to work very well as a indicator considering the default themes even if it is all white.

I didn’t found any other method :sweat_smile:

Never worked with docker, so difficult to give you an answer (and you didn’t provide the error message)
One thing you have to take care is, that’s not possible to retrieve the palette until the main window has been created.
And that might be the reason why from scripter it works.

Currently, for BuliCommander:

  • Krita 4.x: I made the check & initialisation when user execute BuliCommander because I know that Krita.instance().activeWindow() will return something (but when plugin is loaded, at Krita’s startup, main window is not yet created and then, error…)
  • Krita 5.0: I connect a function to Krita.instance().notifiers().windowCreated() signal, this allows to do initialization from palette at startup, without need of a manual action of users

So, for a docker, I don’t know. There’s maybe a signal or an event that can be used to determinate the best moment to initialize palette.
Or wait for Krita 5.x (on my side, some function are ready for Krita 5.x, I check current Krita’s version to determinate to activate or not some functionalities…)

Grum999

Note: on my side I’ve changed the origin of QPalette few days ago.

I’ve modified:
palette = Krita.activeWindow().qwindow().palette()
With:
palette = QApplication.palette()

And maybe at Krita’s startup the QApplication.palette() will work better, need to check, not sure which method you’re currently trying (as my change has been committed after I provided you link to my python module)

Grum999

I decided to give this another go since it works on the scripter but not on the boot of a plugin. so I though in just placing it on the timer check I have running so it also updates as soon as you change it too. that really solved me the issue of the not booting up with init. giving it some default values to boot up up helps it to have something to chew on in the meanwhile.

so I ended up with just this in the end:

def Krita_2_Pigment(self):
    # Check current Theme color Value
    krita = QApplication.palette().color(QPalette.Window).value()
    if self.theme_krita != krita:
        # Update System Variable
        self.theme_krita = krita
        # Contrast Gray Calculation
        if self.theme_krita <= 101:
            value = ( 255 - self.theme_krita ) / 255
        elif self.theme_krita >= 153:
            value = ( 255 - self.theme_krita ) / 255
        else:
            value = ( self.theme_krita - 52 ) / 255
        # RGB Code of contrast Gray
        self.theme_pigment = self.HEX_6(value,value,value)

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.