一、简述
最近用了项目需要写了个极简的报警提示小控件,有正常、报警震动、勿扰三种状态切换,主要是加了个震动的小动画效果,代码也很简单,需要的小伙伴直接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 版权协议,转载请附上原文出处链接和本声明。