QT实现闪烁文本(可摆动)

文本闪烁是一种动态效果,可以让文本在界面上以闪烁的方式显示出来。它可以用于增强用户界面的吸引力,提高用户体验,并且在某些情况下有特定的功能和用途。本文介绍了通过Qt实现的文字闪烁的效果。感兴趣的可以试一试。

一、简述

这篇文章主要介绍了通过Qt实现的文字闪烁的效果。

二、 设计思路

主要涉及两个辅助类:

  • QFontMetrics

    用于获取文本字体的像素高度与宽度

  • QBasicTimer

    定时器,用于更新文本绘制。QBasicTimer是计时器的低级类。与QTimer不同,QBasicTimer不会从QObject继承。它不会在经过一定时间后发出timeout()信号,而是将QTimerEvent发送到我们选择的QObject。这使QBasicTimer成为QTimer的更轻量级替代。主要用于高度优化或性能要求较高的应用程序(例如嵌入式应用程序)。

原理:

  • 利用QBasicTimer进行定时刷新。

  • 文本绘制时,使用QColor来设置色调(H)、饱和度(S)、亮度(V),然后计算每一个字符的绘制坐标,进行单个绘制。

三、效果
四、核心代码
1、头文件
#ifndef FLASHLABEL_H
#define FLASHLABEL_H

#include <QWidget>
#include <QBasicTimer>

class FlashLabel : public QWidget
{
    Q_OBJECT
public:
    explicit FlashLabel(QWidget *parent = nullptr);

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

#endif // FLASHLABEL_H
2、实现代码
#include "flashlabel.h"
#include <QPainter>
#include <QTimerEvent>

FlashLabel::FlashLabel(QWidget *parent) : QWidget(parent)
{
    setBackgroundRole(QPalette::Light);//设置颜色主题 QPalette::Light:比Button的亮

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

    step = 0;
    timer.start(60, this);
}

void FlashLabel::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);

    QFontMetrics metrics(font());
    int x = (width() - metrics.horizontalAdvance(text)) / 2;
    int y = (height() + metrics.ascent() - metrics.descent()) / 2;
    QColor color;
    QPainter painter(this);
    for (int i = 0; i < text.size(); ++i)
    {
        //设置单个字符颜色 色调(H)、饱和度(S)、亮度(V)
        int index = (step + i) % 16;
        color.setHsv((15 - index) * 16, 255, 191);
        painter.setPen(color);

        //单个字符绘制
        painter.drawText(x, y ,QString(text[i]));

        //计算下一个字符的x坐标起始点
        x += metrics.horizontalAdvance(text[i]);
    }

}

void FlashLabel::timerEvent(QTimerEvent *event)
{
    if (event->timerId() == timer.timerId())
    {
        ++step;
        update();
    } else
    {
        QWidget::timerEvent(event);
    }
}

到这里,文字闪烁效果就已经实现了,功能比较简单。

五、使用示例

以下是一个简单的示例代码,演示了如何在Qt中使用此控件:

#include "mainwindow.h"
#include "flashlabel.h"
#include <QVBoxLayout>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    FlashLabel *pFlashLabel = new FlashLabel(this);
    pFlashLabel->setText(tr("Hello world!"));

    QWidget *widget = new QWidget(this);
    QVBoxLayout *layout = new QVBoxLayout(widget);
    layout->addWidget(pFlashLabel);
    setCentralWidget(widget);

    resize(360, 145);
}

MainWindow::~MainWindow()
{
}
六、扩展

我们可以修改起始坐标x、y的值,稍作改动之后,让文本有跳动效果。QFontMetrics对象提供有关文本的字体信息。该x变量是水平位置,是表示开始绘制文本的位置。y变量是文本基线的垂直位置。代码如下:

void FlashLabel::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);

    static const int sineTable[16] = {
        0, 38, 71, 92, 100, 92, 71, 38, 0, -38, -71, -92, -100, -92, -71, -38
    };

    QFontMetrics metrics(font());
    int x = (width() - metrics.horizontalAdvance(text)) / 2;
    int y = (height() + metrics.ascent() - metrics.descent()) / 2;
    QColor color;
    QPainter painter(this);
    for (int i = 0; i < text.size(); ++i) {
        int index = (step + i) % 16;
        color.setHsv((15 - index) * 16, 255, 191);
        painter.setPen(color);
        painter.drawText(x, y - ((sineTable[index] * metrics.height()) / 400),
                         QString(text[i]));
        x += metrics.horizontalAdvance(text[i]);
    }
}

效果如下:

使用文本闪烁效果可以增强用户界面的吸引力,提高用户体验,并且在某些情况下有特定的功能和用途。但是需要注意的是,过度使用文本闪烁效果可能会导致界面杂乱和用户疲劳,因此需要适度使用并考虑用户体验。

感谢您阅读我写的文章,并且给予宝贵的时间和耐心。希望我所提供的信息对您有所帮助,并能够对您的生活、工作或学习起到一定的启发和指导作用。如果您对这篇文章有任何疑问或意见,都可以随时向我提出。再次感谢您的支持和关注,祝您生活愉快、工作顺利!

七、源代码下载
相关推荐
hope_wisdom1 分钟前
C++网络编程之SSL/TLS加密通信
网络·c++·ssl·tls·加密通信
erxij6 分钟前
【游戏引擎之路】登神长阶(十四)——OpenGL教程:士别三日,当刮目相看
c++·经验分享·游戏·3d·游戏引擎
Lizhihao_19 分钟前
JAVA-队列
java·开发语言
学习路上_write27 分钟前
FPGA/Verilog,Quartus环境下if-else语句和case语句RT视图对比/学习记录
单片机·嵌入式硬件·qt·学习·fpga开发·github·硬件工程
林开落L36 分钟前
前缀和算法习题篇(上)
c++·算法·leetcode
远望清一色37 分钟前
基于MATLAB边缘检测博文
开发语言·算法·matlab
努力的小雨1 小时前
快速上手 KSQL:轻松与数据库交互的利器
数据库·经验分享
何曾参静谧1 小时前
「Py」Python基础篇 之 Python都可以做哪些自动化?
开发语言·python·自动化
Prejudices1 小时前
C++如何调用Python脚本
开发语言·c++·python
单音GG1 小时前
推荐一个基于协程的C++(lua)游戏服务器
服务器·c++·游戏·lua