用QT实现字体颜色渐变效果——模拟彩色混光键盘
paint.h
#ifndef PAINT_H
#define PAINT_H
#include <QWidget>
#include <QtWidgets>
class Paint : public QWidget
{
Q_OBJECT
public:
explicit Paint(QWidget *parent = nullptr);
~Paint();
private slots:
void onTimeOut();
private:
QLabel **label;
QTimer *timer;
int colorIndex;
int smooth; // 平滑次数
int count; // 变色次数
int period; // 变色周期(ms)
int colorCount;
int letterCount;
};
#endif // PAINT_H
paint.cpp
#include "paint.h"
static const quint32 color[] = {0xFF0000, 0xFFA500, 0xFFFF00, 0xFF00, 0x7FFF, 0xFF, 0x8B00FF};
static const QString letter = "QWERTYUIOPASDFGHJKL;ZXCVBNM,./";
Paint::Paint(QWidget *parent) : QWidget(parent) {
colorIndex = 0;
smooth = 20;
count = 0;
period = 2000;
colorCount = sizeof(color) / sizeof(quint32);
letterCount = letter.size();
label = new QLabel* [letterCount];
QVBoxLayout *vLayout = new QVBoxLayout;
setLayout(vLayout);
QHBoxLayout *hLayout = new QHBoxLayout;
vLayout->addLayout(hLayout);
for (int i=0; i<letterCount; ++i) {
if ( 0 == i%10 && i) {
hLayout = new QHBoxLayout;
vLayout->addLayout(hLayout);
QWidget *widget = new QWidget;
widget->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
widget->setMinimumWidth(4*i);
hLayout->addWidget(widget);
}
label[i] = new QLabel(letter[i]);
label[i]->setFont(QFont("",50));
hLayout->addWidget(label[i]);
}
// setWindowFlags(Qt::FramelessWindowHint); // 去除标题栏,必须去除,否则会有一层背景导致不透明
// setAttribute(Qt::WA_TranslucentBackground, true); // 背景透明
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(onTimeOut()));
timer->start(period / (smooth * colorCount));
}
Paint::~Paint() { delete [] label; }
void Paint::onTimeOut() {
for (int i=0; i<letterCount; ++i) {
// 起始颜色和目标颜色
QColor cs( color[(colorIndex+i%10) % colorCount] );
QColor ce( color[(colorIndex+1+i%10) % colorCount] );
// 计算RGB分量的相差量
double deltaR = ce.red() - cs.red();
double deltaG = ce.green() - cs.green();
double deltaB = ce.blue() - cs.blue();
// 逐次向目标色靠近,即可完成渐变过程
int red = cs.red() + deltaR * count / smooth;
int green = cs.green() + deltaG * count / smooth;
int blue = cs.blue() + deltaB * count / smooth;
// 通过设置QSS定制文字边框和颜色
label[i]->setStyleSheet(QString(".QLabel { border:2px solid; border-radius:5px; color: rgb(%1, %2, %3); }").arg(red).arg(green).arg(blue));
}
if ( ++count > smooth ) {
count = 0;
colorIndex = (colorIndex+1) % colorCount;
}
}
效果: