qtqt5qtquick2qtquickcontrols2qqmlapplicationengine

QtQuick colour palette for disabled widgets


I am working on a Qt (QML) application that requires darker color palette. Based on some examples I created a qtquickcontrols2.conf file with the following content:

[Controls]
Style=Fusion

[Fusion\Palette]
AlternateBase=#353535
Base=#191919
BrightText=red
Button=#353535
ButtonText=white
Highlight=#2a82da
HighlightedText=gray
Link=#2a82da
Text=white
ToolTipBase=white
ToolTipText=white
Window=#353535
WindowText=#dddddd

The colour palette works just fine for active mode of widgets. However, disabled widgets look exactly the same as active ones. I did not find a way to add colours for disabled widgets to the config file. It seems that it can't be done.

Then I had an idea to create lighter version of active palette in application main.

QPalette& updateDisabledColors(QPalette &palette)
{
    palette.setColor(QPalette::Disabled, QPalette::Window, palette.window().color().lighter());
    palette.setColor(QPalette::Disabled, QPalette::WindowText, palette.windowText().color().lighter());
    palette.setColor(QPalette::Disabled, QPalette::Base, palette.base().color().lighter());
    palette.setColor(QPalette::Disabled, QPalette::AlternateBase, palette.alternateBase().color().lighter());
    palette.setColor(QPalette::Disabled, QPalette::Text, palette.text().color().lighter());
    palette.setColor(QPalette::Disabled, QPalette::Button, palette.button().color().lighter());
    palette.setColor(QPalette::Disabled, QPalette::ButtonText, palette.buttonText().color().lighter());
    palette.setColor(QPalette::Disabled, QPalette::BrightText, palette.brightText().color().lighter());
    palette.setColor(QPalette::Disabled, QPalette::Link, palette.link().color().lighter());
    palette.setColor(QPalette::Disabled, QPalette::Highlight, palette.highlight().color().lighter());
    palette.setColor(QPalette::Disabled, QPalette::HighlightedText, palette.highlightedText().color().lighter());

    return palette;
}


int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QApplication app(argc, argv);

// Tried to change palette here also

    QQmlApplicationEngine engine;

    engine.load(QUrl(QStringLiteral("qrc:/qml/main.qml")));
    if (engine.rootObjects().isEmpty()) {
        return -1;
    }

    auto palette = app.palette();
    palette = updateDisabledColors(palette);
    app.setPalette(palette);

    return app.exec();
}

The palette acquired from the app is not the one defined in qtquickcontrol2.conf.

What is the proper way to modify palette colours for disabled widgets when using QML?


Solution

  • As far as I can tell, setting the Fusion style Palette in qtquickcontrols2.conf does not update the default Q[Gui]Application palette. But the opposite works -- the default Controls2 palette is the system-wide default QPalette which can be set with Q[Gui]Application::setPalette(). So you could set all the color groups in C++ code, like you do now for just the Disabled group.

    Looking at the relevant code, it also looks like you can specify a Disabled subgroup in qtquickcontrols2.conf (e.g. Fusion/Palette/Disabled). I'm not sure which versions of Qt this is available in, nor do I see this documented anywhere.

    ADDED: Looks like the Palette and subgroups are read from conf file since at least Qt 5.10 (which is also when the Control::palette property was introduced).