渐变有三种:QLinearGradient, QConicalGradient and QRadialGradient
1、QLinearGradient
QLinearGradient 是线性渐变,也就是颜色的各个分量(red, green, blue)在两点之间的变化是线性的,需要设置渐变的起始和结束坐标、颜色,超出渐变范围的填充方式,它并不能单独的使用,而是要和 QBrush 一起使用实现填充效果,主要有以下一些函数:
// 创建 QLinearGradient,同时设置起始和结束坐标
QLinearGradient(const QPointF &start, const QPointF &finalStop)
QLinearGradient(qreal x1, qreal y1, qreal x2, qreal y2)
// 设置渐变的颜色,position 的取值范围是 [0.0, 1.0]
setColorAt(qreal position, const QColor &color)
// 超出渐变范围后的填充方式,默认使用 PadSpread:
// QGradient::PadSpread
// QGradient::RepeatSpread
// QGradient::ReflectSpread
void setSpread(Spread method)
// 使用渐变创建画刷
QBrush(const QGradient &gradient)
下图来自 QLinearGradient 的帮助文档,两个灰色的点表示渐变的起始和结束位置,从黄色渐变到有点发灰的黄色,同时展示了超出渐变范围时的三种填充方式:
为了介绍 QLinearGradient 的使用,下面的程序使用线性渐变,在垂直方向从红色渐变到蓝色,填充矩形 QRect(20, 20, 200, 200):
void LinearGradientWidget::paintEvent(QPaintEvent *) {
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
QRect rect(20, 20, 200, 200);
// 渐变开始的坐标为 (20, 20), 结束的坐标为 (20, 220)
QLinearGradient gradient(rect.x(), rect.y(),
rect.x(), rect.y() + rect.height());
gradient.setColorAt(0.0, Qt::red);
gradient.setColorAt(1.0, Qt::blue);
// 超出渐变范围后的填充方式
gradient.setSpread(QGradient::ReflectSpread);
painter.setPen(Qt::NoPen);
painter.setBrush(gradient); // QBrush(const QGradient &gradient)
painter.drawRect(rect);
}
如果不用 QLinearGradient,怎么实现上面的渐变效果呢?也既是线性渐变的原理是什么呢?
以求线段上任意点的坐标为例,如图,已知线段的两端点 A(x1, y1),B(x2, y2),求线段上任意一点 M 的坐标 (x, y),则
根据两点的距离公式可以求出线段的长度 |AB|(用 || 表示线段的长度)
t = |AM| / |AB|;
因为 |AM| >= 0 且 |AM| <= |AB|,所以 t 的值为 [0.0, 1.0],用 length 表示 |AB|,则
x = x1 + t * length
y = y1 + t * length
t 为 0.0 时 M 和 A 重合,t 为 1.0 时 M 和 B 重合。
因为 t 的值为 0 到 1 之间,所以可以用循环求出 AB 上任意点的坐标
for