在Python中检测操作系统的暗黑模式。

18

我正在用Python编写一个带有GUI的小程序,我使用tkinter来实现。我想要为我的程序添加深色模式支持。Mac OS、Ubuntu(至少Gnome)和Windows 10都具有系统范围的“深色模式”设置,这将使所有程序自动运行在深色主题下。

但是,我该如何检查这些设置(最好是独立于操作系统)以便于我的程序知道它需要呈现浅色模式还是深色模式?我找到了许多像darkdetect等库,可以处理MacOS的深色模式,但我没有找到适用于Ubuntu和Windows 10的任何内容。

我知道我可以使用ttkthemes之类的工具为我的程序创建深色主题设计,但是我如何知道何时启用它?在Windows 10或Ubuntu 20.04上运行的Python脚本怎样才能确定用户是否启用了操作系统设置中的深色模式?

理想情况下,我正在寻找适用于所有三种操作系统的解决方案/代码,但如果不可能(我怀疑),那么针对每个操作系统的代码也可以。我只是无法在任何地方找到非MacOS系统的正确示例。


darkdetect 也适用于 Windows。 - Daniyal Warraich
darkdetect 现在也支持使用 Gtk 的 Linux Xfce。我刚试过,在 Debian 11 上可以正常工作。 - Teekin
5个回答

10

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,如果不能,则可能不是在使用Windows操作系统
  • 搜索相关的注册表项,如果未找到,则假定暗模式未启用
  • 如果注册表键存在并且值设置为0,则启用暗模式

7

在 macOS 上,暗黑/浅色模式位于外观选项中,可以通过在终端上运行简单的命令 defaults read -g AppleInterfaceStyle 来检查。

  • 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.


我们可以简单地编写一个函数,如果启用了深色模式则返回 True,如果启用了浅色模式则返回 False

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


3
这个问题不是关于非Mac OS吗? - Maximilian Peters
@MaximilianPeters:是的,我回答这个问题只是因为我认为不需要安装任何外部库,只需几行代码就可以完成。我只是在分享我的知识,希望能帮到他。 - Saad

3

我本来想自己创建一个通用函数,但看起来已经有人为所有操作系统创建了一个不错的软件包:https://pypi.org/project/darkdetect/

import darkdetect

darkdetect.theme()
# Returns 'Dark'

darkdetect.isDark()
# Returns True

darkdetect.isLight()
# Returns False

2
在Gnome中,暗模式开关取决于主题。以下功能应该适用于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


-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"    

这在我的Kde-Plasma中运行良好。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接