Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Qt StyleSheet system is invalidating QPalette; how to make them work together?

I have in one of my projects a QwtPlot where I want to configure its colors in an harmonious way - that is, e.g., if the background color is white, the axis should be black, etc.. Now I could do this in a "hardcoded way": each time the background color (the reference) is changed, I look at an array of previously defined colors for the axis and set the given color in the array for that axis. But this is quite "out of fashion" and I would like a more automated way.

Seeking help here, Uwe told me to use QwtPlot::setPalette(color), and it works great by itself. The problem is that the QwtPlot is child of a series of QWidget-based widgets whose colors should be configured in a global style sheet file and I noticed that when the style sheet for one of those widgets is configured, it invalidates the QwtPlot's call to setPalette. It is as if I should choose between them: if I'm going to use at least one call to setPalette in a given widget, then none of its parents up to the main widget (a QMainWindow in my case) should be configured with the style sheet system. This seems what this part of the documentation about setPalette is saying:

Warning: Do not use this function in conjunction with Qt Style Sheets.(source)

, but it would seem that was supposed to be the case only when using a global call to setPalette.

So my questions are: is there a way to solve this problem in an harmonious way? Or do I need to abandon the style sheet system for that part of the software and use just palettes instead? I tried to make the style sheet configuration in a more "localized" way - that is trying to say to the system "this stylesheet configuration is only valid for this widget; don't perpetuate it to its child widgets", with no success. If this is really possible (and therefore I probably chosed the wrong syntax), I would like to know.

like image 992
Momergil Avatar asked Jan 06 '15 17:01

Momergil


1 Answers

In your style sheet, use .QWidget {...} rather than QWidget {...} for styles that you don't want subclasses to inherit. If applied to all the QwtPlotparents this will allow you to use setPalette again.

Nothing can save you however if you try to mix style sheets and palettes for the same widget, the style sheet will always supersede it, so beware!

EDIT:

another option is to subclass QwtPlot and use designable properties for the canvas, allowing you to use style sheets to set the property, but also have programmatic access to the value.

#include <QWidget>
#include <QBrush>    
#include <qwt_plot.h>

class QPlot : public QwtPlot
{
    Q_OBJECT

    Q_PROPERTY(QBrush canvasBackground READ canvasBackground 
        WRITE setCanvasBackground DESIGNABLE true)

public:

    QPlot(const QwtText &title, QWidget* parent = nullptr) : QwtPlot(title, parent);

    void setCanvasBackground(const QBrush &brush) 
    { 
        QwtPlot::setCanvasBackground(brush); 
        // set the axes color as well, maybe YIQ method?
    };
    QBrush canvasBackground() const
    {
         return QwtPlot::canvasBackground;
    }
};

In your style sheet you could then set the canvas background with

qproperty-canvasBackground: #000000;

The contrasting color algorithm I think is a bit out of scope for this answer, but these questions may help: Programmatically choose high-contrast colors, How do I invert a colour / color?

like image 131
Nicolas Holthaus Avatar answered Nov 15 '22 05:11

Nicolas Holthaus