Qt自定义圆周动画

由于项目需求,需要把一张图片做圆周运动,用到了属性动画,坐标计算等。

在编写代码的过程中,由于太长时间没用sin,cos函数忘了是用弧度为单位,汗呀惊恐

下面把代码贴出来

/*
 * 圆周运动动画
 * */
#ifndef CircleAnimationWidget_H
#define CircleAnimationWidget_H

#include <QWidget>
#define PI  3.1415
class QPropertyAnimation;

class CircleAnimationWidget : public QWidget
{
    Q_OBJECT
    //注册属性,用于动画
    Q_PROPERTY(qreal percent READ percent WRITE setPercent)
public:
    explicit CircleAnimationWidget(QWidget *parent = 0);
    explicit CircleAnimationWidget(const QString &icon, \
                                   const qreal &radius, QWidget *parent = 0);
    void setCircleInfo(const QString &icon, const qreal &radius);
    void startAnimation();
    void stopAnimation();
    void setPercent(const qreal &per);
    const qreal &percent()
    {
        return m_percent;
    }
protected:
    void paintEvent(QPaintEvent *);
private slots:
    //更新坐标值
    void updatePos();
private:
    //计算坐标值
    QPoint mathPoint();
    QPoint mathPoint(const QPoint ¢erPos, const qreal &percent, const qreal &radius);
    void initAnimation();
private:
    qreal m_percent;//百分比
    qreal m_radius;//半径
    QPoint m_centerPos;//圆点坐标

    QPropertyAnimation *m_percentAnimation;
    QPixmap m_pix;
    QPoint m_point;//图片坐标
    QPoint m_originPoint;//图片原始坐标
};

#endif // CircleAnimationWidget_H

#include "circleanimationwidget.h"
#include <QPainter>
#include <QPropertyAnimation>
#include <qmath.h>

CircleAnimationWidget::CircleAnimationWidget(QWidget *parent) :
    QWidget(parent)
{
    this->setAttribute(Qt::WA_TranslucentBackground);
}

CircleAnimationWidget::CircleAnimationWidget(const QString &icon,\
                                             const qreal &radius, QWidget *parent) : QWidget(parent)
{
    this->setAttribute(Qt::WA_TranslucentBackground);
    this->setCircleInfo(icon, radius);
}

void CircleAnimationWidget::initAnimation()
{
    m_percentAnimation = new QPropertyAnimation(this, "percent");
    m_percentAnimation->setDuration(2000);
    m_percentAnimation->setStartValue(0.0);
    m_percentAnimation->setEndValue(1.0);
    m_percentAnimation->setLoopCount(-1); //无限循环,只有调用stop才会停止
}

void CircleAnimationWidget::startAnimation()
{
    m_percentAnimation->start();
}

void CircleAnimationWidget::stopAnimation()
{
    m_percentAnimation->stop();
    m_point = m_originPoint;
    m_percent = 0;
    update();
}

void CircleAnimationWidget::setCircleInfo(const QString &icon, const qreal &radius)
{
    m_pix.load(icon);
    m_percent = 0;
    m_radius = radius;
    int pixW = m_pix.width();
    int pixH = m_pix.height();
    m_centerPos.setX(radius);
    m_centerPos.setY(radius);
    m_originPoint.setX(radius*2);
    m_originPoint.setY(radius);
    m_point = m_originPoint;

    this->setFixedSize(pixW + radius*2, pixH + radius*2);
    this->initAnimation();
}

void CircleAnimationWidget::setPercent(const qreal &per)
{
    m_percent = per;
    updatePos();
}

void CircleAnimationWidget::updatePos()
{
    m_point = mathPoint();
    update();
}

QPoint CircleAnimationWidget::mathPoint()
{
    return this->mathPoint(m_centerPos, m_percent, m_radius);
}

QPoint CircleAnimationWidget::mathPoint(const QPoint ¢erPos, const qreal &percent, const qreal &radius)
{
    qreal dx = radius * qCos(percent * ( 2 * PI)) + centerPos.x();//计算x坐标
    qreal dy = radius * qSin(percent * ( 2 * PI)) + centerPos.y(); // 计算y坐标
    return QPoint(dx, dy);
}

void CircleAnimationWidget::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.drawPixmap(m_point, m_pix);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值