1. 程式人生 > >用QT實現字型顏色漸變效果——模擬彩色混光鍵盤

用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;
    }
}

效果: