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
相关推荐
leiming644 分钟前
c++ QT 开发第二天,用ui按钮点亮实体led
开发语言·qt·ui
hqwest1 小时前
码上通QT实战04--主窗体布局
开发语言·css·qt·布局·widget·layout·label
leiming61 小时前
c++ qt开发第一天 hello world
开发语言·c++·qt
赵民勇3 小时前
QML Base Type 详解
qt
hqwest3 小时前
码上通QT实战07--主窗体消息栏设计
开发语言·qt·qt事件·主窗体·stackedwidget
hqwest3 小时前
码上通QT实战06--导航按钮事件
开发语言·qt·mousepressevent·qfont·qpainter·qlineargradient·setbrush
CC.GG4 小时前
【Qt】常用控件----容器类控件(QGroupBox、QTabWidget )以及布局管理器
开发语言·qt
缘如风4 小时前
Qt Creator 断点调试断点停不住
开发语言·qt
hqwest5 小时前
码上通QT实战05--绘制导航按钮
开发语言·css·qt·自定义控件·qframe·布局ui
雄大5 小时前
Qt QPushButton 实战:点击、切换、分组功能
qt