mnelab
mnelab copied to clipboard
Add theme detection for Windows
Currently light/dark theme detection works only on macOS. On Windows and Linux, Qt apps still don't have native dark theme support 😞.
Alright, detection works now, but there are two problems (at least as of Qt 5.15.4, I'm still hoping things will improve with PyQt6/PySide6 but I haven't tested this):
- Qt doesn't detect theme changes on the fly, only on application start. It seems like there's no
QEvent.PaletteChange
emitted on Windows and GNOME/Linux. - It seems like there is no built-in Qt dark theme on Windows and GNOME/Linux, because only the icons change with the app theme.
In summary, switching between dark/light modes currently works only on macOS. We could add limited support for Windows and GNOME/Linux by adapting the theme only upon application start. That would at least be better than nothing. To do this, we need to manually change the palette as mentioned here: https://stackoverflow.com/a/56851493/1112283
from PyQt5.QtCore import QCoreApplication
from PyQt5.QtGui import QPalette, QColor
# dark theme
palette = QPalette()
palette.setColor(QPalette.Window, QColor(53, 53, 53))
palette.setColor(QPalette.WindowText, Qt.white)
palette.setColor(QPalette.Base, QColor(25, 25, 25))
palette.setColor(QPalette.AlternateBase, QColor(53, 53, 53))
palette.setColor(QPalette.ToolTipBase, Qt.black)
palette.setColor(QPalette.ToolTipText, Qt.white)
palette.setColor(QPalette.Text, Qt.white)
palette.setColor(QPalette.Button, QColor(53, 53, 53))
palette.setColor(QPalette.ButtonText, Qt.white)
palette.setColor(QPalette.BrightText, Qt.red)
palette.setColor(QPalette.Link, QColor(42, 130, 218))
palette.setColor(QPalette.Highlight, QColor(42, 130, 218))
palette.setColor(QPalette.HighlightedText, Qt.black)
QCoreApplication.instance().setPalette(palette)
# TODO: switch palette back to light theme
Finally, if we decide to integrate these changes for Windows and GNOME/Linux, we should switch to Darkdetect instead of rolling our own interface_style()
function.
We could give the Fusion style a shot (on Windows at least), maybe light/dark modes work with that style (https://www.qt.io/blog/dark-mode-on-windows-11-with-qt-6.5).
Edit: Yes, the Fusion style adapts to light and dark modes. The title bar stays light though, and the icons do not use their light variants when in dark mode, so some tweaking is still required. But in principle, adding this line to __init__.py
does most of the work:
app.setStyle("Fusion")
Fixed by #398.