How to recognize that an application is running in dark theme on Linux?
Asked Answered
S

2

10

I've developed an application which uses qscintilla as a text editor. I also implemented custom lexer to highlight language specific keywords. So far styles for highlighted keywords are hardcoded in mine application and it looks quite ok in the default theme on Windows/Linux(Ubuntu)/Mac.

The problems appears when user chooses a dark theme (on Linux). Depending on QScintilla version some parts of editor do reflect current theme colors while other don't. Moreover mine custom styles render dark blue letters on dark grey background.

I'm looking for some Qt class, which will allow me access of the current system theme. I do not want to define styles for mine application widgets. I want to know what is system default non-proportional font, what is it's size, color, ... If I knew that dark scheme is used I would choose complementary colors for keyword highlighting.

I checked docs for QStyle, QPlatformTheme and other qt classes and it seems to me that these serve more for defining of new styles, then for describing the current style.

Spruill answered 8/3, 2016 at 22:10 Comment(0)
G
6

For the system colours, you can use the group/role of the QPalette class.

For the system fonts, you can create a QFont using e.g. "Serif", "Sans Serif", "Monospace", etc with an appropriate style hint to discover the defaults.

NB:

From the Qt Docs:

Warning: Some styles do not use the palette for all drawing, for instance, if they make use of native theme engines. This is the case for both the Windows Vista and the macOS styles.

Ginni answered 8/3, 2016 at 22:53 Comment(7)
How can this be used? I've tried to use QPalette().color(QPalette::Window) and it returns white color in Dark theme in Ubuntu 20.04. Thus it's not a working method.Wulf
@AlexanderDyagilev It works fine for me on arch linux using qt-5.15.1, and all earlier versions that I've used going back to qt-3. I have also used it on other platforms (but not ubuntu) without any problems. I can only guess that it's an ubuntu-specific problem, or maybe an issue with your particular setup. Try testing on a different system or with a different theme.Ginni
Can you please provide a working example then? E.g. something like bool isDarkTheme() {...}.Wulf
@AlexanderDyagilev From the Qt docs: "Warning: Some styles do not use the palette for all drawing, for instance, if they make use of native theme engines". This isn't a programming problem, so examples aren't going to help. If the Qt APIs aren't returning the expected colours on your system, you need to find out why. Did you try the tests I suggesterd?Ginni
It does not work on any platform I've tried (using Qt 5.12.9): Windows/MacOS/Android. So I guess the method in this answer is just not working. Or I'm doing something wrong. That's why I asked you to provide any working (for you) example.Wulf
@AlexanderDyagilev The method works exactly as documented by Qt, and it solves the problem stated in the question. The OP only asked about dark themes on Linux, and specifically excluded Windows, Ubuntu and Mac. However, for greater clarity, I have now added a direct quote about the issue with native theme engines to my answer (even though it's not directly relevant to the original question).Ginni
@AlexanderDyagilev On my arch linux system, which doesn't use a native theme engine, QPalette().color(QPalette.Window).name() returns '#edecec', as expected.Ginni
E
7

Here is some python code using QPalette that works for me on Linux:

label = QLabel("am I in the dark?")
text_hsv_value = label.palette().color(QPalette.WindowText).value()
bg_hsv_value = label.palette().color(QPalette.Background).value()
dark_theme_found = text_hsv_value > bg_hsv_value
Ereshkigal answered 25/10, 2021 at 9:30 Comment(5)
Clever solution. In qml this can be adapted to palette.windowText.hsvValue > palette.window.hsvValueClarisaclarise
Great trick, thanks! However, for me it only seems to work on XFCE (there, I'm comparing the QApplication->style()->standardPalette() colors, since I'm overwriting my application's palette). For Gnome and KDE this somehow doesn't seem to work :(. Any ideas?Ventris
I'm using this with KDE on tumbleweed. Perhaps getting the palette from a newly constructed QLabel is important/relevant in some way. I going in the opposite direction, trying to fit in with the OS/standard palette.Ereshkigal
One thing I've noticed, is that using the palette() method appears to return a copy. For example, when using QLineEdit I call .palette() twice, once to retrieve the normal palette, and then a second time to create an invalid_value_pallet for which I modify the colors, I can then toggle the palettes using .setPalette()in response to user input.Ereshkigal
So Smart and day saving :) 👌Gendron
G
6

For the system colours, you can use the group/role of the QPalette class.

For the system fonts, you can create a QFont using e.g. "Serif", "Sans Serif", "Monospace", etc with an appropriate style hint to discover the defaults.

NB:

From the Qt Docs:

Warning: Some styles do not use the palette for all drawing, for instance, if they make use of native theme engines. This is the case for both the Windows Vista and the macOS styles.

Ginni answered 8/3, 2016 at 22:53 Comment(7)
How can this be used? I've tried to use QPalette().color(QPalette::Window) and it returns white color in Dark theme in Ubuntu 20.04. Thus it's not a working method.Wulf
@AlexanderDyagilev It works fine for me on arch linux using qt-5.15.1, and all earlier versions that I've used going back to qt-3. I have also used it on other platforms (but not ubuntu) without any problems. I can only guess that it's an ubuntu-specific problem, or maybe an issue with your particular setup. Try testing on a different system or with a different theme.Ginni
Can you please provide a working example then? E.g. something like bool isDarkTheme() {...}.Wulf
@AlexanderDyagilev From the Qt docs: "Warning: Some styles do not use the palette for all drawing, for instance, if they make use of native theme engines". This isn't a programming problem, so examples aren't going to help. If the Qt APIs aren't returning the expected colours on your system, you need to find out why. Did you try the tests I suggesterd?Ginni
It does not work on any platform I've tried (using Qt 5.12.9): Windows/MacOS/Android. So I guess the method in this answer is just not working. Or I'm doing something wrong. That's why I asked you to provide any working (for you) example.Wulf
@AlexanderDyagilev The method works exactly as documented by Qt, and it solves the problem stated in the question. The OP only asked about dark themes on Linux, and specifically excluded Windows, Ubuntu and Mac. However, for greater clarity, I have now added a direct quote about the issue with native theme engines to my answer (even though it's not directly relevant to the original question).Ginni
@AlexanderDyagilev On my arch linux system, which doesn't use a native theme engine, QPalette().color(QPalette.Window).name() returns '#edecec', as expected.Ginni

© 2022 - 2024 — McMap. All rights reserved.