xam
xam

Reputation: 155

Horizontal and vertical QLineargradient

I'm trying to generate a clickable HVS colorspace widget using QGraphicsView. The background of the whole QGraphicsView shall look like the image below (without jpeg-artefacts). Clicking at position (x,y) shall give the color under the cursor.

Horizontal Rainbow pattern darkening vertically

I don't want to use the image directly, instead I thought about using QLinearGradient in both directions (horizontal & vertical) using Qt stylesheets.

Simply using horizontal colorstops is straight forward, but I can't figure out how to add the additional vertical (white-color-black) gradient.

What I got so far (inside constructor of inherited class from QGraphicsView) is:

QColor hsvColor[6];
hsvColor[0].setHsv(0, 255, 255);
hsvColor[1].setHsv(60, 255, 255);
hsvColor[2].setHsv(120, 255, 255);
hsvColor[3].setHsv(180, 255, 255);
hsvColor[4].setHsv(240, 255, 255);
hsvColor[5].setHsv(300, 255, 255);

QString styleH = QString("background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0,") +
                 QString("stop:0.000 rgba(%1, %2, %3, 255),").arg( hsvColor[0].red() ).arg( hsvColor[0].green() ).arg( hsvColor[0].blue() ) +
                 QString("stop:0.166 rgba(%1, %2, %3, 255),").arg( hsvColor[1].red() ).arg( hsvColor[1].green() ).arg( hsvColor[1].blue() ) +
                 QString("stop:0.333 rgba(%1, %2, %3, 255),").arg( hsvColor[2].red() ).arg( hsvColor[2].green() ).arg( hsvColor[2].blue() ) +
                 QString("stop:0.500 rgba(%1, %2, %3, 255),").arg( hsvColor[3].red() ).arg( hsvColor[3].green() ).arg( hsvColor[3].blue() ) +
                 QString("stop:0.666 rgba(%1, %2, %3, 255),").arg( hsvColor[4].red() ).arg( hsvColor[4].green() ).arg( hsvColor[4].blue() ) +
                 QString("stop:0.833 rgba(%1, %2, %3, 255),").arg( hsvColor[5].red() ).arg( hsvColor[5].green() ).arg( hsvColor[5].blue() ) +
                 QString("stop:1.000 rgba(%1, %2, %3, 255));").arg( hsvColor[0].red() ).arg( hsvColor[0].green() ).arg( hsvColor[0].blue() );
this->setStyleSheet(styleH);

This gives me:

Horizontal Rainbow pattern without vertical darkening

How can I draw a xy-gradient like above using QLinearGradient and Qt stylesheets?

Upvotes: 8

Views: 10649

Answers (1)

0x1gene
0x1gene

Reputation: 3458

The trick here is to have 2 gradients in your QGraphicsView, one set as the background for the colors (left to right), one set as the foreground (top to bottom).

// a colored background based on hue
QLinearGradient colorGradient = QLinearGradient(0, 0, width(), 0);
colorGradient.setSpread(QGradient::RepeatSpread);
colorGradient.setColorAt(0, QColor(255,255,255));
colorGradient.setColorAt(1, currentHue);

QLinearGradient blackGradient = QLinearGradient(0, 0, 0, height());
blackGradient.setSpread(QGradient::RepeatSpread);
blackGradient.setColorAt(0, QColor(0,0,0,0));
blackGradient.setColorAt(1, QColor(0,0,0,255));

QBrush colorGradiantBrush = QBrush(colorGradient);
QBrush blackGradiantBrush = QBrush(blackGradient);
scene.setBackgroundBrush(colorGradiantBrush);
scene.setForegroundBrush(blackGradiantBrush);

The code above gives you a palette with one color like this:

result


For the foreground, I used a transparent to black — you will need a white to transparent, to black. And for the background, I used a white to a specific color — you can use your spectrum that you already have.

Upvotes: 10

Related Questions