Qt小程序之自绘震动铃铛提示控件

  • Post author:
  • Post category:小程序




一、简述

最近用了项目需要写了个极简的报警提示小控件,有正常、报警震动、勿扰三种状态切换,主要是加了个震动的小动画效果,代码也很简单,需要的小伙伴直接copy即可。

在这里插入图片描述



二、代码之路



BellWidget.h

#include <QWidget>
#include <QPropertyAnimation>

enum BellState 
{
    BellNormal,     // 正常;
    BellAlarm,      // 报警;
    BellMute        // 静音;
};

class BellWidget : public QWidget
{
    Q_OBJECT

public:
    BellWidget(QWidget *parent = Q_NULLPTR);

    // 设置/获取 当前是否报警;
    void setIsAlarm(bool isAlarm);
    bool getIsAlarm();
    
    // 设置铃铛状态;
    void setBellState(BellState bellState);

    // 设置当前摇铃角度范围;
    void setShakeAngle(int angle);

    // 设置摇铃频率;
    void setShakeFrequency(int frequency);

private:
    void paintEvent(QPaintEvent *event);

    void mousePressEvent(QMouseEvent *event);

signals:
    // 发送点击铃铛信号;
    void signalBellClicked();

private:
    // 变换角度;
    int m_bellAngle;
    QPropertyAnimation *m_moveAnimation;
    bool m_isAlarm;
    int m_shakeAngle;
    int m_shakeFrequency;
    BellState m_bellState;
};



BellWidget.cpp

#include "BellWidget.h"
#include <QPainter>
#include <QMouseEvent>

BellWidget::BellWidget(QWidget *parent)
    : QWidget(parent)
    , m_isAlarm(false)
    , m_shakeAngle(15)
    , m_shakeFrequency(150)
    , m_bellState(BellNormal)
{
    m_moveAnimation = new QPropertyAnimation(this, "");
    m_moveAnimation->setDuration(m_shakeFrequency);
    m_moveAnimation->setEasingCurve(QEasingCurve::Linear);
    m_moveAnimation->setStartValue(m_shakeAngle);
    m_moveAnimation->setEndValue(-m_shakeAngle);


    connect(m_moveAnimation, &QPropertyAnimation::valueChanged, this, [=](const QVariant &value) {
        m_bellAngle = value.toInt();
        update();
    });
    connect(m_moveAnimation, &QPropertyAnimation::finished, this, [=] {
        QAbstractAnimation::Direction dir = m_moveAnimation->direction();
        if (dir == QAbstractAnimation::Forward)
        {
            m_moveAnimation->setDirection(QAbstractAnimation::Backward);
        }
        else if (dir == QAbstractAnimation::Backward)
        {
            m_moveAnimation->setDirection(QAbstractAnimation::Forward);
        }
        m_moveAnimation->start();
        update();
    });

    this->setFixedSize(QSize(80, 80));
    
    connect(this, &BellWidget::signalBellClicked, this, [=] {
        this->setIsAlarm(!this->getIsAlarm());
    });

}

void BellWidget::setIsAlarm(bool isAlarm)
{
    m_isAlarm = isAlarm;
    if (isAlarm)
    {
        m_moveAnimation->start();
        setBellState(BellAlarm);
    }
    else
    {
        m_moveAnimation->stop();
        setBellState(BellNormal);
    }
}

bool BellWidget::getIsAlarm()
{
    return m_isAlarm;
}

void BellWidget::setBellState(BellState bellState)
{
    m_bellState = bellState;
    update();
}

void BellWidget::setShakeAngle(int angle)
{
    m_shakeAngle = angle;
    m_moveAnimation->setStartValue(m_shakeAngle);
    m_moveAnimation->setEndValue(-m_shakeAngle);
}

void BellWidget::setShakeFrequency(int frequency)
{
    m_shakeFrequency = frequency;
    m_moveAnimation->setDuration(m_shakeFrequency);
}

void BellWidget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::SmoothPixmapTransform);
    // 为了防止绘制铃铛pixmap摇晃时不出边界,加了border;
    // 此处border需要根据控件大小进行调整;
    int border = 20;
    switch (m_bellState)
    {
    case BellNormal:
    {
        painter.drawPixmap(this->rect().adjusted(border, 0, -border, -0), QPixmap(":/Resources/BellNormal.png"));
    }
        break;
    case BellAlarm:
    {
        painter.translate(this->rect().center());
        painter.rotate(m_bellAngle);
        painter.translate(-this->rect().center());
        painter.drawPixmap(this->rect().adjusted(border, 0, -border, 0), QPixmap(":/Resources/BellAlarm.png"));
    }
        break;
    case BellMute:
    {
        painter.drawPixmap(this->rect().adjusted(border, 0, -border, -0), QPixmap(":/Resources/BellMute.png"));
    }
        break;
    default:
        break;
    }    
}

void BellWidget::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton)
    {
        emit signalBellClicked();
    }
    else if (event->button() == Qt::RightButton)
    {
        setBellState(BellMute);
    }
}

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述



版权声明:本文为GoForwardToStep原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。