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

一、简述

最近用了项目需要写了个极简的报警提示小控件,有正常、报警震动、勿扰三种状态切换,主要是加了个震动的小动画效果,代码也很简单,需要的小伙伴直接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);
    }
}

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 7
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt是一个跨平台的C++应用程序开发框架,它提供了丰富的GUI(图形用户界面)和功能组件,其中包括自件。自件是指通过重写制函数来实现自定义外观和行为的件。 在Qt中,自件通常是从QWidget类派生而来的子类。要使用自件,你需要重写QWidget的paintEvent()函数,并在其中进行制操作。paintEvent()函数会在件需要重新制时被调用,你可以在该函数中使用Qt提供的图工具进行制。 以下是使用paintEvent()函数自件的基本步骤: 1. 创建一个继承自QWidget的子类,并重写其paintEvent()函数。 2. 在paintEvent()函数中,创建一个QPainter对象,并使用该对象进行制操作。 3. 使用QPainter提供的图函数(如drawRect()、drawText()等)来实现你想要的外观效果。 4. 根据需要,可以在其他事件处理函数中添加交互逻辑,例如鼠标点击事件等。 下面是一个简单的示例代码,展示了如何使用paintEvent()函数自一个简单的矩形件: ```cpp #include <QtWidgets> class MyWidget : public QWidget { public: MyWidget(QWidget *parent = nullptr) : QWidget(parent) {} protected: void paintEvent(QPaintEvent *event) override { Q_UNUSED(event); QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); // 设置抗锯齿 painter.fillRect(rect(), Qt::blue); // 制蓝色背景 painter.setPen(Qt::white); // 设置画笔颜色为白色 painter.drawRect(rect().adjusted(10, 10, -10, -10)); // 制带边距的矩形 } }; int main(int argc, char *argv[]) { QApplication app(argc, argv); MyWidget widget; widget.resize(200, 200); widget.show(); return app.exec(); } ``` 这个示例中,我们创建了一个名为MyWidget的自定义件,重写了其paintEvent()函数,在其中使用QPainter对象制了一个带有蓝色背景和白色边框的矩形。在main()函数中,我们创建了一个应用程序对象,并显示了这个自定义件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值