Qt小程式之自繪震動鈴鐺提示控制元件
阿新 • • 發佈:2019-02-06
一、簡述
最近用了專案需要寫了個極簡的報警提示小控制元件,有正常、報警震動、勿擾三種狀態切換,主要是加了個震動的小動畫效果,程式碼也很簡單,需要的小夥伴直接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); } }