天天看點

qt 繪制閃爍波浪文本

qt 繪制閃爍波浪文本

該執行個體為qt 自帶的demo 執行個體程式,搜尋Wiggly Example 即可

主要原理是利用定時器定時修改字元的色調和y軸位置

class WigglyWidget : public QWidget
{
    Q_OBJECT

public:
    WigglyWidget(QWidget *parent = 0);

public slots:
    void setText(const QString &newText) { text = newText; }

protected:
    void paintEvent(QPaintEvent *event) override;
    void timerEvent(QTimerEvent *event) override;

private:
    QBasicTimer timer;
    QString text;
    int step;
};
           
WigglyWidget::WigglyWidget(QWidget *parent)
    : QWidget(parent)
{
    setBackgroundRole(QPalette::Midlight);
    setAutoFillBackground(true);

    QFont newFont = font();
    newFont.setPointSize(newFont.pointSize() + 20);
    setFont(newFont);

    step = 0;
    timer.start(60, this);
}
//! [0]

//! [1]
void WigglyWidget::paintEvent(QPaintEvent * /* event */)
//! [1] //! [2]
{
    static const int sineTable[16] = {
        0, 38, 71, 92, 100, 92, 71, 38, 0, -38, -71, -92, -100, -92, -71, -38
    };

    QFontMetrics metrics(font());
    //找到中心,計算繪制文本的起點
    //metrics.horizontalAdvance 傳回文本的水準像素寬度
    //metrics.ascent() 傳回從基線到最低點字元延伸到的距離 metrics.descent() 傳回從基線到字元延伸到的最高位置的距離
    //metrics.ascent() - metrics.descent() 文本的像素高度
    int x = (width() - metrics.horizontalAdvance(text)) / 2;
    int y = (height() + metrics.ascent() - metrics.descent()) / 2;
    QColor color;
//! [2]

//! [3]
    QPainter painter(this);
//! [3] //! [4]
    for (int i = 0; i < text.size(); ++i) {
        int index = (step + i) % 16;
        //設定HSV模式下該顔色元件中對應的色調(hue),飽和度(saturation),明亮(lightness),透明度(alpha)
        //每一個文本都不一樣,随着定時器的重新整理step改變,色調也在改變
        color.setHsv((15 - index) * 16, 255, 191);
        painter.setPen(color);
        //改變每一個文本的y軸,随着定時器的重新整理step改變,每一個字元的y軸也在變化;每次繪制一個字元,然後移動x軸到下一個字元
        painter.drawText(x, y - ((sineTable[index] * metrics.height()) / 400),
                         QString(text[i]));
        x += metrics.horizontalAdvance(text[i]);
    }
}
//! [4]

//! [5]
void WigglyWidget::timerEvent(QTimerEvent *event)
//! [5] //! [6]
{
    if (event->timerId() == timer.timerId()) {
        ++step; //定時修改該值,paintEvent 中利用該值更改文本的色調和字元y軸的位置
        update();
    } else {
        QWidget::timerEvent(event);
    }
//! [6]
}
           

繼續閱讀