qt自制文本,应该没什么用

cpp 复制代码
#include "GlitchTextWidget.h"
#include <QDebug>
#include <QMouseEvent>
#include <QEnterEvent>
#include <QAbstractAnimation>

GlitchTextWidget::GlitchTextWidget(const QString& text, QWidget *parent)
    : QWidget(parent),
    m_text(text),
    m_speed(1.0),
    m_enableShadows(true),
    m_enableOnHover(false),
    m_glitchFrameIndex(0),
    m_isMouseOver(false)
{
    QFontDatabase::addApplicationFont("://Cyberpunk.ttf");
    setFont(QFont("Cyberpunk", 72, QFont::Black));

    setMouseTracking(true);

    m_animationAfter = new QPropertyAnimation(this, "clipRectAfter");
    m_animationBefore = new QPropertyAnimation(this, "clipRectBefore");

    m_animationAfter->setLoopCount(-1);
    m_animationBefore->setLoopCount(-1);

    m_animationAfter->setEasingCurve(QEasingCurve::Linear);
    m_animationBefore->setEasingCurve(QEasingCurve::Linear);

    m_glitchTimer = new QTimer(this);
    connect(m_glitchTimer, &QTimer::timeout, this, [this](){
        if (m_clipKeyframes.isEmpty()) {
            updateClipKeyframes();
        }

        if (!m_clipKeyframes.isEmpty()) {
            QMargins margins = m_clipKeyframes[m_glitchFrameIndex];

            int clipY = (height() * margins.top()) / 100;
            int clipHeight = height() - clipY - (height() * margins.bottom()) / 100;

            m_clipRectAfter = QRect(0, clipY, width(), clipHeight);
            m_clipRectBefore = QRect(0, clipY, width(), clipHeight);

            m_glitchFrameIndex = (m_glitchFrameIndex + 1) % m_clipKeyframes.size();
            update();
        }
    });

    setupAnimations();
    if (!m_enableOnHover) {
        startGlitchAnimation();
    }
}

void GlitchTextWidget::setText(const QString& text) {
    if (m_text != text) {
        m_text = text;
        update();
        updateGeometry();
    }
}

void GlitchTextWidget::setSpeed(qreal speed) {
    if (m_speed != speed) {
        m_speed = speed;
        setupAnimations();
        if (!m_enableOnHover && m_glitchTimer->isActive()) {
            startGlitchAnimation();
        } else if (m_enableOnHover && m_isMouseOver) {
            startGlitchAnimation();
        }
    }
}

void GlitchTextWidget::setEnableShadows(bool enable) {
    if (m_enableShadows != enable) {
        m_enableShadows = enable;
        update();
    }
}

void GlitchTextWidget::setEnableOnHover(bool enable) {
    if (m_enableOnHover != enable) {
        m_enableOnHover = enable;
        if (m_enableOnHover) {
            stopGlitchAnimation();
        } else {
            startGlitchAnimation();
        }
        update();
    }
}

void GlitchTextWidget::setCustomClassName(const QString& className) {
    m_customClassName = className;
}

void GlitchTextWidget::updateClipKeyframes() {
    m_clipKeyframes.clear();
    m_clipKeyframes.append(QMargins(0, 20, 0, 50));
    m_clipKeyframes.append(QMargins(0, 10, 0, 60));
    m_clipKeyframes.append(QMargins(0, 15, 0, 55));
    m_clipKeyframes.append(QMargins(0, 25, 0, 35));
    m_clipKeyframes.append(QMargins(0, 30, 0, 40));
    m_clipKeyframes.append(QMargins(0, 40, 0, 20));
    m_clipKeyframes.append(QMargins(0, 10, 0, 60));
    m_clipKeyframes.append(QMargins(0, 15, 0, 55));
    m_clipKeyframes.append(QMargins(0, 25, 0, 35));
    m_clipKeyframes.append(QMargins(0, 00, 0, 40));
    m_clipKeyframes.append(QMargins(0, 20, 0, 50));
    m_clipKeyframes.append(QMargins(0, 10, 0, 60));
    m_clipKeyframes.append(QMargins(0, 15, 0, 55));
    m_clipKeyframes.append(QMargins(0, 25, 0, 35));
    m_clipKeyframes.append(QMargins(0, 30, 0, 111));
    m_clipKeyframes.append(QMargins(0, 40, 0, 20));
    m_clipKeyframes.append(QMargins(0, 20, 0, 50));
    m_clipKeyframes.append(QMargins(0, 10, 0, 60));
    m_clipKeyframes.append(QMargins(0, 15, 0, 55));
    m_clipKeyframes.append(QMargins(0, 25, 0, 35));
    m_clipKeyframes.append(QMargins(0, 30, 0, 40));
}

void GlitchTextWidget::setupAnimations() {
    updateClipKeyframes();

    int totalAfterDurationMs = static_cast<int>(m_speed * 3000);
    int totalBeforeDurationMs = static_cast<int>(m_speed * 2000);

    if (m_clipKeyframes.isEmpty()) {
        m_glitchTimer->setInterval(30);
    } else {
        m_glitchTimer->setInterval(totalAfterDurationMs / m_clipKeyframes.size());
    }

    m_animationAfter->setDuration(totalAfterDurationMs);
    m_animationBefore->setDuration(totalBeforeDurationMs);
}

void GlitchTextWidget::startGlitchAnimation() {
    if (!m_glitchTimer->isActive()) {
        m_glitchFrameIndex = 0;
        m_glitchTimer->start();
    }
}

void GlitchTextWidget::stopGlitchAnimation() {
    if (m_glitchTimer->isActive()) {
        m_glitchTimer->stop();
        m_clipRectAfter = rect();
        m_clipRectBefore = rect();
        update();
    }
}

void GlitchTextWidget::paintEvent(QPaintEvent *event) {
    Q_UNUSED(event);
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.setFont(font());

    painter.fillRect(rect(), QColor("#060606"));

    QFontMetrics fm(font());
    int textWidth = fm.horizontalAdvance(m_text);
    int textHeight = fm.height();
    int textX = (width() - textWidth) / 2;
    int textY = (height() - textHeight) / 2 + fm.ascent();

    painter.setPen(QColor(Qt::white));
    painter.drawText(textX, textY, m_text);

    if (!m_enableOnHover || (m_enableOnHover && m_isMouseOver)) {
        painter.save();
        painter.setPen(QColor(Qt::red));
        painter.setClipRect(m_clipRectAfter);
        painter.drawText(textX - 10, textY, m_text);
        painter.restore();

        painter.save();
        painter.setPen(QColor(Qt::cyan));
        painter.setClipRect(m_clipRectBefore);
        painter.drawText(textX + 10, textY, m_text);
        painter.restore();
    }
}

void GlitchTextWidget::enterEvent(QEnterEvent *event) {
    m_isMouseOver = true;
    if (m_enableOnHover) {
        startGlitchAnimation();
    }
    QWidget::enterEvent(event);
}

void GlitchTextWidget::leaveEvent(QEvent *event) {
    m_isMouseOver = false;
    if (m_enableOnHover) {
        stopGlitchAnimation();
    }
    QWidget::leaveEvent(event);
}

QSize GlitchTextWidget::sizeHint() const {
    QFontMetrics fm(font());
    int widthHint = fm.horizontalAdvance(m_text) + 20;
    int heightHint = fm.height() + 20;
    return QSize(widthHint, heightHint);
}

QRect GlitchTextWidget::clipRectAfter() const { return m_clipRectAfter; }
void GlitchTextWidget::setClipRectAfter(const QRect& rect) { m_clipRectAfter = rect; update(); }

QRect GlitchTextWidget::clipRectBefore() const { return m_clipRectBefore; }
void GlitchTextWidget::setClipRectBefore(const QRect& rect) { m_clipRectBefore = rect; update(); }
cpp 复制代码
#ifndef GLITCHTEXTWIDGET_H
#define GLITCHTEXTWIDGET_H

#include <QWidget>
#include <QPropertyAnimation>
#include <QPainter>
#include <QTimer>
#include <QFontMetrics>
#include <QEnterEvent>
#include <QAbstractAnimation>
#include <QFontDatabase>
#include <QDebug> 

class GlitchTextWidget : public QWidget
{
    Q_OBJECT
    Q_PROPERTY(QRect clipRectAfter READ clipRectAfter WRITE setClipRectAfter)
    Q_PROPERTY(QRect clipRectBefore READ clipRectBefore WRITE setClipRectBefore)

public:
    explicit GlitchTextWidget(const QString& text, QWidget *parent = nullptr);

    void setText(const QString& text);
    void setSpeed(qreal speed);
    void setEnableShadows(bool enable);
    void setEnableOnHover(bool enable);
    void setCustomClassName(const QString& className);

protected:
    void paintEvent(QPaintEvent *event) override;
    void enterEvent(QEnterEvent *event) override;
    void leaveEvent(QEvent *event) override;
    QSize sizeHint() const override;

private:
    QString m_text;
    qreal m_speed;
    bool m_enableShadows;
    bool m_enableOnHover;
    QString m_customClassName;
    QPropertyAnimation *m_animationAfter;
    QPropertyAnimation *m_animationBefore;
    QTimer *m_glitchTimer;
    int m_glitchFrameIndex;
    QList<QMargins> m_clipKeyframes;
    bool m_isMouseOver;

    QRect m_clipRectAfter;
    QRect m_clipRectBefore;

    QRect clipRectAfter() const;
    void setClipRectAfter(const QRect& rect);

    QRect clipRectBefore() const;
    void setClipRectBefore(const QRect& rect);

    void setupAnimations();
    void startGlitchAnimation();
    void stopGlitchAnimation();
    void updateClipKeyframes();
};

#endif // GLITCHTEXTWIDGET_H
相关推荐
神仙别闹2 小时前
基于QT(C++)实现(图形界面)连连看
java·c++·qt
sailing-data2 小时前
【UI Qt】入门笔记
开发语言·qt·ui
mengzhi啊2 小时前
qt自绘制,蜂巢网格,感觉没什么用
qt
Y1rong3 小时前
QT之串口调试助手
qt
小尧嵌入式4 小时前
深入理解C/C++指针
java·c语言·开发语言·c++·qt·音视频
零小陈上(shouhou6668889)4 小时前
增加PyQt5界面的交通流量预测(模型为CNN_GRU,CNN_BiGRU_ATTENTION,LSTM,Python代码)
qt·cnn·gru
繁星蓝雨5 小时前
Qt优雅的组织项目结构一(使用pri进行模块化配置)——————附带详细示例代码
开发语言·qt·pri
繁星蓝雨6 小时前
Qt优雅的组织项目结构二(基于Qt5使用CmakeList进行模块化配置)——————附带详细示例代码
开发语言·qt·cmake·cmakefile.txt·.cmake
edjxj7 小时前
解决QT可执行文件在不同缩放大小的电脑上显示差异
服务器·数据库·qt