更改应用程序调色板运行时,无需重新启动应用程序

时间:2017-12-25 19:11:30

标签: c++ qt

我成功地使用了黑暗主题来融合" Qt5应用程序的风格。我想添加功能来切换主题。如果要求用户重新启动应用程序,则没有问题,在应用程序启动时正确初始化调色板。但我希望能够在没有重新启动的情况下执行此运行时。大多数小部件都支持这种可能性,但其他一些小部件(例如QComboBoxQSpinBoxQTreeView)不支持。这可以通过以下代码段来证明 - 只需按下按钮'重置样式'你可以看到小部件的某些部分如何正确改变,但其他部分没有。我在Windows 10上使用最新的Qt 5.10。在我看来这是Qt bug,但有没有解决方法或黑客?

这是我的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();
}

这是widget.h

#pragma once

#include <QWidget>

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);

};

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);
}

这是黑暗的:

enter image description here

重置样式后

和这个:

enter image description here

1 个答案:

答案 0 :(得分:0)

根据此错误报告中的讨论:https://bugreports.qt.io/browse/QTBUG-65475问题似乎与某些样式中的pixmap缓存有关。更改调色板后,不会从全局QPixmapCache中清除相应的像素图。

可能的解决方法是手动清除完整的QPixmapCache:

QPixmapCache::clear(); 

具有明显的性能影响,以防必须重新计算许多像素图。