Simply put, this is not possible, at least not just by setting the color of the widget.
The reason resides on the fact that QIcon doesn't represent an image or a file: it actually is an abstraction layer that is queried by widgets when they need to display a pixmap at a desired size.
Every icon has its own icon engine, responsible of actually drawing the pixmap when required), and when loading icons from a file the related icon engine is used.
For instance, when loading an SVG file, QIcon internally creates an instance of a QIconEngine subclass that is able to read SVG files and render their contents when required.
When icons are drawn (for instance in a button), the Qt style normally calls the pixmap() function of the icon, which internally calls the pixmap(), which has the following argument signature:
QIconEngine::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state)
As you can see, there is absolutely no reference about the context in which the icon is drawn (such as the text color), so there is no way to change the icon rendering just by trying to change the palette, as that context is never passed on.
QIcon and QIconEngine have a paint() function, which passes a QPainter reference, so, in theory it would be possible to at least try to get the current pen/brush colors from the painter, but there is absolutely no guarantee that those would be set with the appropriate foreground color; also, that function is only called from some classes and under specific circumstances: even the internal QStyleSheetStyle still uses pixmap() for button icons.
Considering the above, what you ask is not directly possible: if you want to use different color schemes, you need to have different icon sets for each one of them.
There is a way to simplify the way those different icon sets are chosen, though, which is to use a little known feature of QDir, the setSearchPaths() function.
The procedure is the following:
- create the two icon sets, while keeping the same file names, and put them in two different directories (this also works for Qt resources);
- call
setSearchPaths() with an appropriate prefix and the target folder for the current color scheme, for instance:
hints = QApplication.styleHints()
if hints.colorScheme() == Qt.ColorScheme.Dark:
path = '<path-to-light-icons>'
else:
path = '<path-to-dark-icons>'
QDir.setSearchPaths('icons', [path])
- then, whenever you need to set an icon, you can use the above prefix:
someButton.setIcon(QIcon('icons:someIcon.svg'))
Note that calling setSearchPaths() doesn't work dynamically: it won't automatically change the icon once called, which means that:
- it should be called before any QIcon is created and used (usually at the program startup);
- if you want to change color scheme at runtime, you need to find a way to automatize the icon reload; for instance, you could store the generic icon name, connect to the
colorSchemeChanged signal and call setIcon() again with the same path, including the prefix used above;