相信大家都用过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();
}
然后运行看一下是不是非常简单