// // Created by Louis on 25-4-1. // #include "QAntAbstractButton.h" QAntAbstractButton::QAntAbstractButton(QWidget *parent) : QWidget(parent) { setAttribute(Qt::WA_Hover); // // 设置布局方案 setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); setCursor(Qt::PointingHandCursor); setAttribute(Qt::WA_TranslucentBackground); setStyleSheet("QWidget { border: none; background: transparent; }"); // setWindowFlags(windowFlags() | Qt::FramelessWindowHint); // 创建阴影效果 m_shadowEffect = new QGraphicsDropShadowEffect(this); m_shadowEffect->setBlurRadius(0); m_shadowEffect->setColor(Qt::transparent); m_shadowEffect->setOffset(0, 0); setGraphicsEffect(m_shadowEffect); // 创建动画组 m_animationGroup = new QParallelAnimationGroup(this); // 创建模糊半径动画 QPropertyAnimation* blurAnimation = new QPropertyAnimation(m_shadowEffect, "blurRadius", this); blurAnimation->setDuration(300); blurAnimation->setStartValue(0); blurAnimation->setEndValue(25); blurAnimation->setEasingCurve(QEasingCurve::OutQuad); m_animationGroup->addAnimation(blurAnimation); // 创建颜色动画 QPropertyAnimation* colorAnimation = new QPropertyAnimation(m_shadowEffect, "color", this); colorAnimation->setDuration(300); colorAnimation->setEasingCurve(QEasingCurve::OutQuad); m_animationGroup->addAnimation(colorAnimation); connect(m_animationGroup, &QParallelAnimationGroup::finished, this, [this]() { m_shadowEffect->setColor(Qt::transparent); m_shadowEffect->setBlurRadius(0); }); } QAntAbstractButton::~QAntAbstractButton() { if (m_animationGroup) { delete m_animationGroup; m_animationGroup = nullptr; } if (m_shadowEffect) { delete m_shadowEffect; m_shadowEffect = nullptr; } } QString QAntAbstractButton::text() const { return m_text; } void QAntAbstractButton::setText(const QString &text) { if (text != m_text) { m_text = text; update(); emit textChanged(text); } } QIcon QAntAbstractButton::icon() const { return m_icon; } void QAntAbstractButton::setIcon(const QIcon &icon) { if (icon.cacheKey() != m_icon.cacheKey()) { m_icon = icon; update(); emit iconChanged(icon); } } QSize QAntAbstractButton::iconSize() const { return m_iconSize; } void QAntAbstractButton::setIconSize(const QSize &size) { if (m_iconSize != size) { m_iconSize = size; updateGeometry(); update(); } } QMargins QAntAbstractButton::padding() const { return m_padding; } void QAntAbstractButton::setPadding(const QMargins &margins) { if (m_padding != margins) { m_padding = margins; updateGeometry(); update(); } } QAntAbstractButton::ButtonState QAntAbstractButton::currentState() const { return m_state; } void QAntAbstractButton::paintText(QPainter &painter, const QRect &textRect) { painter.save(); painter.setPen(palette().color(foregroundRole())); painter.setFont(font()); painter.drawText(textRect, Qt::AlignCenter, m_text); painter.restore(); } void QAntAbstractButton::paintIcon(QPainter &painter, const QRect &iconRect) { QIcon::Mode mode = QIcon::Normal; if (!isEnabled()) { mode = QIcon::Disabled; } else if (m_state == PressedState) { mode = QIcon::Selected; } m_icon.paint(&painter, iconRect, Qt::AlignCenter, mode); } void QAntAbstractButton::paintFocusIndicator(QPainter &painter) { painter.save(); QPen pen(palette().highlight(), 1, Qt::DotLine); painter.setPen(pen); painter.setBrush(Qt::NoBrush); painter.drawRect(rect().adjusted(1, 1, -1, -1)); painter.restore(); } void QAntAbstractButton::paintBackground(QPainter &painter) { painter.fillRect(rect(), Qt::transparent); } void QAntAbstractButton::paintBorder(QPainter &painter) { // 移除边框绘制 painter.save(); QPen pen(palette().shadow(), 1); painter.setPen(pen); painter.setBrush(Qt::NoBrush); painter.drawRect(rect().adjusted(0, 0, -1, -1)); painter.restore(); } QRect QAntAbstractButton::calculateTextRect(const QRect &contentsRect) const { QFontMetrics fm(font()); QRect textRect = fm.boundingRect(contentsRect, Qt::AlignCenter, m_text); if (!m_icon.isNull()) { textRect.moveLeft(contentsRect.left() + m_iconSize.width() + 4); } return textRect; } QRect QAntAbstractButton::calculateIconRect(const QRect &contentsRect) const { return QRect(contentsRect.left(), contentsRect.center().y() - m_iconSize.height() / 2, m_iconSize.width(), m_iconSize.height()); } void QAntAbstractButton::paintEvent(QPaintEvent *event) { Q_UNUSED(event); QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); paintBackground(painter); switch (m_state) { case NormalState: paintNormalState(painter); break; case HoverState: paintHoverState(painter); break; case PressedState: paintPressedState(painter); break; case DisabledState: paintDisabledState(painter); break; case LoadingState: paintLoadingState(painter); break; } // paintBorder(painter); QRect contentsRect = rect().marginsRemoved(m_padding); if (!m_icon.isNull() && m_state != LoadingState) { QRect iconRect = calculateIconRect(contentsRect); paintIcon(painter, iconRect); } if (!m_text.isEmpty() && m_state != LoadingState) { QRect textRect = calculateTextRect(contentsRect); paintText(painter, textRect); } if (hasFocus()) { paintFocusIndicator(painter); } } void QAntAbstractButton::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton && !m_loading && isEnabled()) { m_mousePressed = true; updateButtonState(PressedState); emit pressed(); event->accept(); } } void QAntAbstractButton::mouseReleaseEvent(QMouseEvent *event) { if (m_mousePressed && event->button() == Qt::LeftButton) { m_mousePressed = false; if (rect().contains(event->pos())) { startRippleEffect(); emit clicked(); updateButtonState(HoverState); } else { updateButtonState(NormalState); } } emit release(); event->accept(); } void QAntAbstractButton::mouseMoveEvent(QMouseEvent *event) { if (m_mousePressed) { if (rect().contains(event->pos())) { updateButtonState(PressedState); } else { QWidget::mouseMoveEvent(event); } } } void QAntAbstractButton::enterEvent(QEnterEvent *event) { if (isEnabled() && !m_loading && !m_mousePressed) { updateButtonState(HoverState); } QWidget::enterEvent(event); } void QAntAbstractButton::leaveEvent(QEvent *event) { if (isEnabled() && !m_loading) { updateButtonState(NormalState); } QWidget::leaveEvent(event); } void QAntAbstractButton::focusInEvent(QFocusEvent *event) { update(); QWidget::focusInEvent(event); } void QAntAbstractButton::focusOutEvent(QFocusEvent *event) { update(); QWidget::focusOutEvent(event); } void QAntAbstractButton::changeEvent(QEvent *event) { if (event->type() == QEvent::EnabledChange) { if (isEnabled()) { updateButtonState(NormalState); } else { updateButtonState(DisabledState); } emit enabledChanged(isEnabled()); } QWidget::changeEvent(event); } void QAntAbstractButton::updateButtonState(ButtonState newState) { if (newState == m_state) return; ButtonState oldState = m_state; m_state = newState; update(); } void QAntAbstractButton::startRippleEffect() { // 设置初始状态 QColor effectColor = rippleColor(); effectColor.setAlpha(120); m_shadowEffect->setColor(effectColor); m_shadowEffect->setBlurRadius(0); // 更新颜色动画 QPropertyAnimation* colorAnim = qobject_cast(m_animationGroup->animationAt(1)); if (colorAnim) { effectColor.setAlpha(0); colorAnim->setStartValue(m_shadowEffect->color()); colorAnim->setEndValue(effectColor); } // 开始动画组 m_animationGroup->start(); }