Qt,c++,vc仿QQ窗口抖动,抖动时长,抖动偏移值均可自定义

相信大家都用过QQ的窗口抖动,有关qt的实现在这里给出一个非常简单原理和思路

先看效果图,GIF效果确实有些失真,不过凑合看

 

首先第一步在继承自QWidget或QFrame以及QDialog或QMainWindow的窗口类的头定义中定义变量如下

//动画属性指针,指针名可自定义
//如果不想在头文件中包含QPropertyAnimation 那么请在class作用域外申明class QPropertyAnimation;并且在窗口类申明上面
QPropertyAnimation *pShakeAnimation= nullptr;

头文件全部示例代码如下

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class QPropertyAnimation;
class Widget : public QWidget
{
  Q_OBJECT

public:
  Widget(QWidget *parent = nullptr);
  ~Widget();

private slots:
  void on_pushButton_clicked();

private:
  Ui::Widget *ui;
  QPropertyAnimation *pShakeAnimation = nullptr;
};
#endif // WIDGET_H

然后在窗口类初始化或构造函数中创建动画属性指针,代码如下

  pShakeAnimation= new QPropertyAnimation(this,"pos");

最后您可以在需要处理动画的地方添加动画代码,比如按钮单击事件信号槽中处理,核心代码示例如下

  QPoint pos = this->pos();
  //如果动画尚未结束,就先结束动画然后继续
  if(pShakeAnimation->state() == QPropertyAnimation::Running)
      pShakeAnimation->stop();
  //也可以在动画尚未结束之时直接返回等待动画结束后方可第二次启动抖动动画

  //设置动画时长,这里可以用配置,一般来说设置600足够,可以通过配置属性来实现自定义时长
  pShakeAnimation->setDuration(10000);

  //记录初始位置
  pShakeAnimation->setStartValue(pos);

  int offset =0;                    //设置偏移量
  double dOffset = (double)1/300;   //设置抖动次数进度递增因子,300是指抖动的次数为三百次
  double dIndex =dOffset;           //初始抖动进度因子

  //代码中的300是指抖动三百次
  for(int i=1;i<300;i++){
      offset = i%2==0?-10:10;       //计算偏移量,偶数和奇数时不同
      dIndex += dOffset;            //进度递增

      /*注意这里的示例只是抖动次数为偶数时向左向上偏移10像素
        抖动次数为奇数时向右和向下偏移10像素往复循环。如果要实现其他的抖动规则情自行实现偏移规则*/

      //设置动画属性进度和偏移值
      pShakeAnimation->setKeyValueAt(dIndex,pos + QPoint((int)offset,(int)offset));
    }

  pShakeAnimation->setEndValue(pos);
  pShakeAnimation->start();

源文件全部代码如下

#include "widget.h"
#include "ui_widget.h"
#include <QPropertyAnimation>

Widget::Widget(QWidget *parent)
  : QWidget(parent)
  , ui(new Ui::Widget)
{
  ui->setupUi(this);
  pShakeAnimation = new QPropertyAnimation(this,"pos");
}

Widget::~Widget()
{
  delete ui;
}

//按钮单击事件信号槽内实现动画功能
void Widget::on_pushButton_clicked()
{
  QPoint pos = this->pos();
  //动画还没有结束就先立马停止,防止用户不停的点击
  if(pShakeAnimation->state() == QPropertyAnimation::Running)
    {
      pShakeAnimation->stop();
    }
  pShakeAnimation->setDuration(600);
  pShakeAnimation->setStartValue(pos);

  int offset =0;
  double dOffset = (double)1/30;
  double dIndex =dOffset;
  for(int i=1;i<30;i++){
      offset = i%2==0?-10:10;
      dIndex += dOffset;
      pShakeAnimation->setKeyValueAt(dIndex,pos + QPoint((int)offset,(int)offset));
    }

  pShakeAnimation->setEndValue(pos);
  pShakeAnimation->start();
}

然后运行看一下是不是非常简单

有关技术交流其它交流可加入QQ群717743458探讨。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值