Darin Beaudreau
Darin Beaudreau

Reputation: 391

QT Dialog has incorrect styling

I've been trying various methods of creating a new dialog that needs to be spawned from the main application.

I created a designer form, nothing special about it, and placed some stock widgets on it. Once I finally got it to launch from the main application properly, I noticed that the widgets have no styling to them. The buttons have no border or embossing, all text is white, and the background color of the buttons and LineEdit object are gray. The code used to launch the dialog is as follows:

    UpdateDialog dialog(NULL);
    dialog.setModal(true);
    dialog.exec();

I figured maybe it was being inherited from the parent widget, so I passed NULL as the parent in the constructor for the dialog object and it still happened.

I found one answer to a similar question online suggesting that you can override inherited stylesheets from the parent by setting a stylesheet for the dialog that basically just looks like:

    #objectName {}

But this has no effect.

Styles applied to the widget after creation seem to work, as if I use the following line, the text color on the buttons becomes black:

    dialog->setStyleSheet("color: rgb(0,0,0)");

Does anyone know what could be causing this behavior? If it matters, we're using Qt 5.6.1 on Scientific Linux (RHEL 6).

EDIT: Here is a picture of the dialog.

Dialog without Styling

There is supposed to be a LineEdit below the label, as well as a button to the right of it, and then two more buttons beneath the LineEdit. Unfortunately the picture quality doesn't let you see it, but there IS a very faint white text where the buttons are supposed to be, so they ARE there, they're just not styled.

EDIT: This styling also seems to get applied to the file dialog I spawn from the update dialog seen above.

Upvotes: 1

Views: 1199

Answers (1)

Former contributor
Former contributor

Reputation: 2576

Qt does not have a strong visual identity of its own. Instead, it tries to provide a native look and feel on all its target platforms. All operating systems include some look-and-feel customization capabilities, but in this area Linux is special, because there is not a single, unique user interface like in Windows and macOS, but there are several. Two well known desktops for Linux (and other Unix-like Operating Systems) are Gnome and KDE. Some distributions install Gnome as default, and a few install the other. Most allow to install both, and the user can choose one at the login screen, or in a desktop configuration setting.

I've never tried Scientific Linux before, but I know Fedora so it wasn't a big deal to install SL6 in a VirtualBox VM to see if I could reproduce your issue (I couldn't!). What I've noticed is that SL6 defaults to Gnome desktop (like RH and Fedora, btw). It does not include Qt5 and it would be difficult to install a Qt5 development environment on it, because it ships an outdated GCC compiler. It is possible to deploy Qt 5.6 applications and libraries on it, though. I've installed KDE in the VM as well with this command:

    sudo yum -y groupinstall "KDE Desktop"

SL6 does not include KDE Plasma, of course, because it requires Qt5. It is KDE4.3 instead, based on Qt4.6. So, in this version, correcting my previous comment, the configuration command for changing/inspecting KDE styles is:

    kcmshell4 style

The default style for KDE4 is Oxygen, as I've deduced by your picture. The color scheme for KDE programs can be configured with this command:

    kcmshell4 colors

To try your scenario, I've made a simple Qt5 Widgets program, which I could deploy on the VM along with the dependent Qt5 libraries. I've used linuxdeployqt to deploy the library and plugins required by the program and create a self contained directory for easy transfer and installing. Anyway, I want to show you how the program looks on my development Linux machine, with my preferred dark-breeze theme:

dark-breeze theme

After deploying the program directory to the SL6 VM, running it under the default Gnome desktop, it looks like this:

gtk+ theme in Gnome

And this is the look when running the program under KDE:

fusion theme in KDE

Remember that we are looking at the same build of the same program, just changing the running environment. Just for your information, I've instrumented my program a little, including in the main() function this debugging statement:

     qDebug() << QStyleFactory::keys();

Which prints this output on Linux:

("Windows", "GTK+", "Fusion")

And also included this debug statement at the main window constructor:

    qDebug() << this->style();

The output of that statement depends on the desktop environment. Under Gnome (which is based on the gtk+ toolkit) it outputs something like this:

QGtkStyle(0x11b39f0, name = "gtk+")

While under the KDE desktop it outputs:

QFusionStyle(0x1428990, name = "fusion")

I hope that at this point you can deduce like me that the origin of your problem must be the color configuration under KDE in your SL6. To prove that theory, please run some other Qt programs and see if they show the same inappropriate colors. In that case, my advice is to fix that configuration (by running kcmshell4 colors) instead of changing the program to force some fixed color scheme, because a good desktop integration is a valued asset for most Linux users.

Anyway, if you want to create a fixed color scheme hardcoded in your program, I give you this example that you can include in your main.cpp to be applied to the whole program.

static QPalette qt_fusionPalette()
{
    QColor backGround(239, 239, 239);
    QColor light = backGround.lighter(150);
    QColor mid(backGround.darker(130));
    QColor midLight = mid.lighter(110);
    QColor base = Qt::white;
    QColor disabledBase(backGround);
    QColor dark = backGround.darker(150);
    QColor darkDisabled = QColor(209, 209, 209).darker(110);
    QColor text = Qt::black;
    QColor hightlightedText = Qt::white;
    QColor disabledText = QColor(190, 190, 190);
    QColor button = backGround;
    QColor shadow = dark.darker(135);
    QColor disabledShadow = shadow.lighter(150);

    QPalette fusionPalette(Qt::black,backGround,light,dark,mid,text,base);
    fusionPalette.setBrush(QPalette::Midlight, midLight);
    fusionPalette.setBrush(QPalette::Button, button);
    fusionPalette.setBrush(QPalette::Shadow, shadow);
    fusionPalette.setBrush(QPalette::HighlightedText, hightlightedText);

    fusionPalette.setBrush(QPalette::Disabled, QPalette::Text, disabledText);
    fusionPalette.setBrush(QPalette::Disabled, QPalette::WindowText, disabledText);
    fusionPalette.setBrush(QPalette::Disabled, QPalette::ButtonText, disabledText);
    fusionPalette.setBrush(QPalette::Disabled, QPalette::Base, disabledBase);
    fusionPalette.setBrush(QPalette::Disabled, QPalette::Dark, darkDisabled);
    fusionPalette.setBrush(QPalette::Disabled, QPalette::Shadow, disabledShadow);

    fusionPalette.setBrush(QPalette::Active, QPalette::Highlight, QColor(48, 140, 198));
    fusionPalette.setBrush(QPalette::Inactive, QPalette::Highlight, QColor(48, 140, 198));
    fusionPalette.setBrush(QPalette::Disabled, QPalette::Highlight, QColor(145, 145, 145));
    return fusionPalette;
}

int main(int argc, char *argv[])
{
    QApplication::setPalette(qt_fusionPalette());
    QApplication a(argc, argv);
    qDebug() << QStyleFactory::keys();

    MainWindow w;
    w.show();
    return a.exec();
}

This light color palette is the same as the standard Qt's "Fusion" palette. If you prefer a dark color scheme, you may find one here.

Upvotes: 2

Related Questions