该实例为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]
}