Reputation: 989
I'm writing a small program in python with a GUI that I'm using tkinter for. What I'd like to do is add dark mode support to my program. Mac OS, Ubuntu (at least Gnome) and Windows 10 all have a system-wide setting for "dark mode" that'll make all programs automatically run with a dark theme.
But how do I check that settings (ideally, OS-independant) so my program knows if it needs to render light mode or dark mode? I found a bunch of libraries like darkdetect that'll handle this for MacOS, but I haven't found anything for Ubuntu and Windows 10.
I know that I can use stuff like ttkthemes to create a dark themed design for my program, but how do I know when to enable that? How can a python script running on Windows 10 or on Ubuntu 20.04 figure out if the user enabled the dark mode in the operating system settings?
Ideally I'm looking for a solution / code that'll work on all three operating systems, but if that's not possible (as I suspect) OS-dependant code would be fine as well. I just can't find proper examples for non-MacOS systems anywhere.
Upvotes: 20
Views: 9361
Reputation: 1
app = QApplication(sys.argv)
decide_theme(app.palette().base().color())
def decide_theme(color: QColor) -> None:
theme: str = ""
r, g, b, a = color.getRgb()
hsp = math.sqrt((0.241 * r * r) + (0.691 * g * g) + (0.068 * b * b))
if hsp > 127.5:
theme = "light"
else:
theme = "dark"
This works fine for me in Kde-Plasma.
Upvotes: -1
Reputation: 5117
I was going to create my own universal function but it looks like someone already made a nice package for all OS: https://pypi.org/project/darkdetect/
import darkdetect
darkdetect.theme()
# Returns 'Dark'
darkdetect.isDark()
# Returns True
darkdetect.isLight()
# Returns False
Upvotes: 6
Reputation: 2015
On Gnome the dark mode switch is theme-dependent. The following function should work on default themes in Ubuntu 20.04:
import subprocess
def detectDarkModeGnome():
'''Detects dark mode in GNOME'''
getArgs = ['gsettings', 'get', 'org.gnome.desktop.interface', 'gtk-theme']
currentTheme = subprocess.run(
getArgs, capture_output=True
).stdout.decode("utf-8").strip().strip("'")
darkIndicator = '-dark'
if currentTheme.endswith(darkIndicator):
return True
return False
Upvotes: 2
Reputation: 3430
On macOS, the Dark/Light mode comes under appearance which can be checked by running a simple command defaults read -g AppleInterfaceStyle
on the terminal.
On Dark mode the command returns
Dark
It'll just return Dark
meaning AppleInterfaceStyle
exist.
On Light mode the same command returns
2020-12-18 17:44:21.870 defaults[20253:5665627]
The domain/default pair of (kCFPreferencesAnyApplication, AppleInterfaceStyle) does not exist
By default light mode is enabled so AppleInterfaceStyle
doesn't exist and that's why it is returning an error.
We can simply make a function which will return True
if the Dark mode is enabled and False
if the Light mode is enabled.
import subprocess
def check_appearance():
"""Checks DARK/LIGHT mode of macos."""
cmd = 'defaults read -g AppleInterfaceStyle'
p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, shell=True)
return bool(p.communicate()[0])
Upvotes: 9
Reputation: 31739
Quick answer for Windows 10
def detect_darkmode_in_windows():
try:
import winreg
except ImportError:
return False
registry = winreg.ConnectRegistry(None, winreg.HKEY_CURRENT_USER)
reg_keypath = r'SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize'
try:
reg_key = winreg.OpenKey(registry, reg_keypath)
except FileNotFoundError:
return False
for i in range(1024):
try:
value_name, value, _ = winreg.EnumValue(reg_key, i)
if value_name == 'AppsUseLightTheme':
return value == 0
except OSError:
break
return False
winreg
can be imported, if not you are probably not using WindowsUpvotes: 10