7

I am making my first GUI application with PyQt5 but it does not currently work with dark mode.

How do you enable dark mode in PyQt5?

I user PyQt5 v5.13.0 and freeze the app with PyInstaller on Mac, Linux and Windows.

If you need more information or some of the code, please tell me.

JSogaard
  • 393
  • 1
  • 4
  • 7
  • What version of Python are you using? I am also using PyQt5 v5.13 (I'm on v5.13.2) with Python 3.7.5 and dark mode is working out-of-the-box on macOS. I have not been able to get it to work on Windows and haven't tried Linux. – Michael Leonard Dec 04 '19 at 01:13

4 Answers4

3

Workaround for macOS X:

  1. Compile your app

  2. Add this into your apps's Info.plist (Found at {APPNAME}/Contents/Info.plist):

    <key>NSRequiresAquaSystemAppearance</key>
    <string>False</string>
    

This can be automated by running PyInstaller from python script and then editing Info.plist using open().

Rocket Nikita
  • 470
  • 2
  • 7
  • 20
  • Hi, can this be done before compiling the app i.e. while development? If yes, can you please explain how? Thanks! – Alex Jones Jan 02 '21 at 14:28
  • 1
    No you can't (unless you are on os below 10.14). I just tested my app on light mode, then compiled and tested with dark mode. – Rocket Nikita Jan 02 '21 at 15:55
  • Bless you. This worked for me with PyQt5 `5.15.2` and Python `3.8.2`. In fact, all I had to do to get this tip to work was amend the `info.plist` file. (Compiled with py2app.) Cheers. – DaveL17 Feb 09 '21 at 16:19
-1

There is no way (Built-in), except for external implementations of Stylesheets, or implementing by yourself..

I highly recommend checking this reply for one of those.

It speaks about this stylesheet.

In this thread there are also ways of how to implement it.

Alexander Santos
  • 1,458
  • 11
  • 22
  • 1
    Have I misunderstood this?: https://www.learnpyqt.com/blog/macos-mojave-dark-mode-support-pyqt5122/ – JSogaard Aug 28 '19 at 11:42
  • After some search, i think it is really supported for MacOS Mojave now. But it seems you don't need to implement anything, it will work *out of the box* if you have dark mode enabled. And Mojave's version needs to be 10.14 (or above). Can you somehow confirm this? You can also try running the application without freezing on a MacOS, and checking if it works the intended way. – Alexander Santos Aug 28 '19 at 14:24
  • I have tried both frozen and directly from source. I shows light mode either way even though my system is set to dark mode. I have also tried disabling and re-enabling dark mode but that does not change anything. I can't figure out what is wrong... – JSogaard Aug 28 '19 at 17:12
  • `We encourage upgrading to Qt 5.12 to get fixes for macOS 10.14 The maximum supported Xcode version for Qt 5.11 and lower is Xcode 9 (SDK 10.13)` Do you have everything in those versions (Except PyQt, that needs 5.12.2)? Found this here: https://blog.qt.io/blog/2018/11/08/qt-macos-10-14-mojave/ – Alexander Santos Aug 28 '19 at 18:16
  • I use PyQt 5.13.0. – JSogaard Sep 02 '19 at 15:03
-1

I struggled with this problem myself (PyQt5 5.14) and have figured out how to make macOS' dark mode work with PyQt5. You have to call QApplication.setStyle('style name here').

For whatever reason, it seems that any color scheme changes lay inert until "activated" by setStyle(). (You can see this if you call QApplication.setPalette(palette) with a custom palette; some colors will change and others won't—until setStyle() is called, upon which all colors finally change.) I can only speculate that dark mode was detected on app start but not activated.

Why it is that color scheme changes don't apply until setStyle() is called, I have no idea. I'm guessing it's a bug in PyQt5.


There are two rules to make the setStyle() trick work:

  1. You must call setStyle() after you've instantiated your QApplication. This is in addition to the setStyle() call before instantiating your QApplication, for a total of two setStyle()s.
  2. setStyle() must be called with a string argument. Giving it a QStyle object does nothing.

So, to have your app sync color schemes with macOS' dark mode:

# Must run before QApplication is instantiated, otherwise certain widget styles will remain unset
PyQt5.QtWidgets.QApplication.setStyle('fusion')

app = YourQApplicationClassHere(sys.argv)

# Must run after QApplication is instantiated, to apply any latent color scheme changes
PyQt5.QtWidgets.QApplication.setStyle('fusion')

Final caveat: If you freeze your app with pyinstaller, not even the setStyle() trick will work.

midrare
  • 2,371
  • 28
  • 48
-1

You can add this two lines at the very start of your code, before importing PyQt5/PySide2:

import os
os.environ["QT_MAC_WANTS_LAYER"] = "1"

No need to install a specific qt version, nor set NSRequiresAquaSystemAppearance to false on Info.plist.

Tested on macOS Mojave, Catalina and Big Sur.

Martí Climent
  • 407
  • 4
  • 9