Reputation: 7954
I am successfully using a dark theme for "fusion" style for Qt5 application. I would like to add the feature to switch the theme. If the user is required to restart the application there is not problem with this, the palette is correctly initialized at application start-up. But I would like to be able to do this run-time, without restarting. Most of widgets support this possibility but some other (e.g. QComboBox
, QSpinBox
, QTreeView
) don't. This can be proved by the following snippet - just press the button 'Reset style' and you can see how some parts of widgets change correctly but other parts don't. I am using the latest Qt 5.10 on Windows 10. This seems to me as Qt bug but is there any workaround or hack?
This is my main.cpp
:
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// apply the dark color scheme
qApp->setStyle("fusion");
QPalette darkPalette;
darkPalette.setColor(QPalette::Window,QColor(53,53,53));
darkPalette.setColor(QPalette::WindowText,Qt::white);
darkPalette.setColor(QPalette::Disabled,QPalette::WindowText,QColor(127,127,127));
darkPalette.setColor(QPalette::Base,QColor(42,42,42));
darkPalette.setColor(QPalette::AlternateBase,QColor(66,66,66));
darkPalette.setColor(QPalette::ToolTipBase,Qt::white);
darkPalette.setColor(QPalette::ToolTipText,Qt::white);
darkPalette.setColor(QPalette::Text,Qt::white);
darkPalette.setColor(QPalette::Disabled,QPalette::Text,QColor(127,127,127));
darkPalette.setColor(QPalette::Dark,QColor(35,35,35));
darkPalette.setColor(QPalette::Shadow,QColor(20,20,20));
darkPalette.setColor(QPalette::Button,QColor(53,53,53));
darkPalette.setColor(QPalette::ButtonText,Qt::white);
darkPalette.setColor(QPalette::Disabled,QPalette::ButtonText,QColor(127,127,127));
darkPalette.setColor(QPalette::BrightText,Qt::red);
darkPalette.setColor(QPalette::Link,QColor(42,130,218));
darkPalette.setColor(QPalette::Highlight,QColor(42,130,218));
darkPalette.setColor(QPalette::Disabled,QPalette::Highlight,QColor(80,80,80));
darkPalette.setColor(QPalette::HighlightedText,Qt::white);
darkPalette.setColor(QPalette::Disabled,QPalette::HighlightedText,QColor(127,127,127));
qApp->setPalette(darkPalette);
Widget w;
w.show();
return a.exec();
}
This is widget.h
:
#pragma once
#include <QWidget>
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
};
and widget.cpp
:
#include "widget.h"
#include <QVBoxLayout>
#include <QComboBox>
#include <QSpinBox>
#include <QTreeWidget>
#include <QPushButton>
#include <QApplication>
#include <QStyleFactory>
Widget::Widget(QWidget *parent) :
QWidget(parent)
{
auto layout = new QVBoxLayout(this);
auto comboBox = new QComboBox();
auto spinBox = new QSpinBox();
auto listWidget = new QTreeWidget();
listWidget->setHeaderLabels(QStringList() << "Column1" << "Column2");
auto button = new QPushButton("Reset style");
// reset the palette to the default 'light' color scheme
connect(button, &QPushButton::clicked,
[] { qApp->setPalette(QStyleFactory::create("fusion")->standardPalette()); });
layout->addWidget(comboBox);
layout->addWidget(spinBox);
layout->addWidget(listWidget);
layout->addWidget(button);
}
This is the dark one:
and this after resetting the style:
UPDATE: This bug has been reported to Qt and already fixed. Well done, Qt team.
Upvotes: 5
Views: 2014
Reputation: 423
According to the discussion in this bug report: https://bugreports.qt.io/browse/QTBUG-65475 the problem seems related to the pixmap caching done in some styles. The appropriate pixmaps are not cleared from the global QPixmapCache after changing the palette.
A possible workaround would be to manually clear the complete QPixmapCache:
QPixmapCache::clear();
With the obvious performance impact, in case a lot of pixmaps have to be recalculated.
Upvotes: 1