Qt动画效果


一、前言

记录下自己使用过程中用到过的动画效果。


提示:以下是本篇文章正文内容,下面案例可供参考

代码如下(示例):

1.包含头文件

#include <QLabel>
#include <QPropertyAnimation>
#include <QParallelAnimationGroup>

2.效果展示

在这里插入图片描述

														切页右滑动

请添加图片描述

														开门切换效果

请添加图片描述

二、窗口动画效果

1.软件启动动画效果

代码如下(示例):

//桌面宽度
int CommonlyUsed::deskWidth()
{
    return qApp->desktop()->availableGeometry().width();
}
//桌面高度
int CommonlyUsed::deskHeight()
{
    return qApp->desktop()->availableGeometry().height();
}
//软件窗口渐进开启
void MainWindow::Software_startup_animation()
{
    //界面动画,窗口右移
    QPropertyAnimation *anim1 = new QPropertyAnimation(this,"pos");
    anim1->setDuration(800);                                //动画持续时间
    anim1->setStartValue(QPoint(deskWidth()/2 - this->width(),deskHeight()/2 - this->height()/2));
    anim1->setEndValue(QPoint(deskWidth()/2 - this->width()/2,deskHeight()/2 - this->height()/2));
    anim1->setEasingCurve(QEasingCurve::Linear);            //设置速度曲线

    //界面动画,渐显效果
    QPropertyAnimation *anim2 = new QPropertyAnimation(this, "windowOpacity");
    anim2 ->setDuration(800);            //动画持续时间
    anim2 ->setStartValue(0);            //设置初始值
    anim2 ->setEndValue(1);              //设置结束值(0-1,透明度由完全透明→不透明)

    //创建并行动画组
    QParallelAnimationGroup *group = new QParallelAnimationGroup(this);
    group->addAnimation(anim1);    //动画组移动动画
    group->addAnimation(anim2);    //动画组添加透明-显现动画   
    group->start(QAbstractAnimation::DeleteWhenStopped);    //动画组中的动画执行完毕后删除对象
}

//界面动画,窗口下降
void MainWindow::Window_down()
{
    QPropertyAnimation *anim1 = new QPropertyAnimation(this,"pos");
    anim1->setDuration(800);
    anim1->setStartValue(QPoint(this->x(),this->y() - this->height()));
    anim1->setEndValue(QPoint(this->x(),this->y()));
    anim1->setEasingCurve(QEasingCurve::Linear);            //设置速度曲线
}
//界面动画,窗口下坠
void frmMain::onDropWindow()
{
    QPropertyAnimation *pAnimation = new QPropertyAnimation(this, "geometry");
    QDesktopWidget *pDesktopWidget = QApplication::desktop();
    int x = (pDesktopWidget->availableGeometry().width() - width()) / 2;
    int y = (pDesktopWidget->availableGeometry().height() - height()) / 2;
    pAnimation->setDuration(1500);
    pAnimation->setStartValue(QRect(x, 0, width(), height()));
    pAnimation->setEndValue(QRect(x, y, width(), height()));
    pAnimation->setEasingCurve(QEasingCurve::OutElastic);
    pAnimation->start(QAbstractAnimation::DeleteWhenStopped);
}
//窗口抖动动画
void MainWindow::ShakeAnimation()
{
    //设置软件在桌面的中心位置
    this->setGeometry(qApp->desktop()->availableGeometry().width()/2 - this->width()/2,
                      qApp->desktop()->availableGeometry().height()/2 - this->height()/2,
                      this->width(),this->height());
    m_animation = new QPropertyAnimation(this,"pos");
    //获取坐标
    QPoint pos = this->pos();
    //动画还没有结束就先立马停止,防止用户不停的点击
    if(m_animation->state() == QPropertyAnimation::Running)
    {
        m_animation->stop();
    }
    m_animation->setDuration(600);
    m_animation->setStartValue(pos);
    m_animation->setKeyValueAt(0.1,pos + QPoint(-12,-12));
    m_animation->setKeyValueAt(0.2,pos + QPoint(0,-4));
    m_animation->setKeyValueAt(0.3,pos + QPoint(4,0));
    m_animation->setKeyValueAt(0.4,pos + QPoint(4,2));
    m_animation->setKeyValueAt(0.5,pos + QPoint(6,-6));
    m_animation->setKeyValueAt(0.6,pos + QPoint(-4,4));
    m_animation->setKeyValueAt(0.7,pos + QPoint(-4,0));
    m_animation->setKeyValueAt(0.8,pos + QPoint(0,8));
    m_animation->setKeyValueAt(0.9,pos + QPoint(12,12));
    m_animation->setEndValue(pos);
    m_animation->start();
}

2.软件关闭动画效果

代码如下(示例):

//关闭动画
void MainWindow::closeMainInterface()
{
    //界面动画,窗口下坠
    QPropertyAnimation* closeAnimation = new QPropertyAnimation(this,"geometry");
    closeAnimation->setStartValue(geometry());
    closeAnimation->setEndValue(QRect(geometry().x(),geometry().y()+height(),width(),0));
    closeAnimation->setDuration(600);
    closeAnimation->setEasingCurve(QEasingCurve::Linear);   //设置速度曲线

    //界面动画,消失效果
    QPropertyAnimation *WindowDisappear_animation = new QPropertyAnimation(this, "windowOpacity");
    WindowDisappear_animation->setDuration(600);
    WindowDisappear_animation->setStartValue(1);
    WindowDisappear_animation->setEndValue(0);

    //创建并行动画组
    QParallelAnimationGroup *group = new QParallelAnimationGroup(this);
    group->addAnimation(closeAnimation);    //动画组添加移动动画
    group->addAnimation(WindowDisappear_animation);         //动画组添加透明-显现动画
    group->start(QAbstractAnimation::DeleteWhenStopped);    //动画组中的动画执行完毕后删除对象
    connect(group, &QParallelAnimationGroup::finished, this, &MainWindow::myCloseWindow); //关闭动画完成后再退出软件
}

//关闭
void MainWindow::myCloseWindow()
{
    QApplication* app;
    app->exit(0);
}

//窗口中心式关闭
void MainWindow::closeAnimation()
{
    setMinimumHeight(1);
    QPropertyAnimation* closeAnimation = new QPropertyAnimation(parentWidget,"geometry");
    closeAnimation->setStartValue(geometry());
    closeAnimation->setEndValue(QRect(geometry().x(),geometry().y()+height()/2,width(),1));
    closeAnimation->setDuration(500);
    closeAnimation->setEasingCurve(QEasingCurve::Linear);
    QPropertyAnimation *WindowDisappear_animation = new QPropertyAnimation(parentWidget, "windowOpacity");
    WindowDisappear_animation->setDuration(500);
    WindowDisappear_animation->setStartValue(1);
    WindowDisappear_animation->setEndValue(0);
    QParallelAnimationGroup *group = new QParallelAnimationGroup(parentWidget);
    group->addAnimation(closeAnimation);
    group->addAnimation(WindowDisappear_animation);
    group->start(QAbstractAnimation::DeleteWhenStopped);
    connect(group, &QParallelAnimationGroup::finished, this, [=](){
        QApplication *app;
        app->quit();
    });
}

anim1->setEasingCurve(QEasingCurve::Linear);
请添加图片描述


三、stackedWidget界面切换的简单动画效果

1.函数实现

代码如下(示例):

//界面切换动画
void MainWindow::Interface_Switching_Animation(int m_currentIndex)
{
	#if 0
    //截取整个图片并向右边移动
    {
    	*QLabel *m_label = new QLabel(ui->stackedWidget);
    	m_label->resize(QSize(ui->stackedWidget->width(),ui->stackedWidget->height()));
    	m_label->setPixmap(ui->stackedWidget->grab());  //捕获当前界面并绘制到label上
    	m_label->setAttribute(Qt::WA_DeleteOnClose);	//设置属性(关闭时删除)
    	m_label->show();								
    	QPropertyAnimation *animation1 = new QPropertyAnimation(m_label,"geometry");
    	animation1->setDuration(1000);  //设置动画时间为1秒
    	animation1->setStartValue(QRect(0,0,ui->stackedWidget->width(),ui->stackedWidget->height()));
    	animation1->setEndValue(QRect(ui->stackedWidget->width()*2,0,ui->stackedWidget->width(),ui->stackedWidget->height()));
    	animation1->setEasingCurve(QEasingCurve::InCubic);   //设置速度曲线(先慢后快)
    	QParallelAnimationGroup *group = new QParallelAnimationGroup;  //并行动画容器(这里只用了一个动画,可以自己添加动画后再添加到并行动画容器中实现多动画效果)
    	group->addAnimation(animation1);
    	group->start(QAbstractAnimation::DeleteWhenStopped);
    	ui->stackedWidget->setCurrentIndex(m_currentIndex);				//切换到对应的界面
    	m_label->raise();       //把label置顶显示
    	connect(group, &QParallelAnimationGroup::finished, this, [=](){m_label->close();}); //关闭动画完成后关闭label
    }
    #endif
} 

#if 1
    //开门动画
    {
        QLabel *m_label = new QLabel(ui->stackedWidget_matrix);
        m_label->resize(QSize(ui->stackedWidget_matrix->width()/2,ui->stackedWidget_matrix->height()));
        m_label->setAttribute(Qt::WA_DeleteOnClose);

        //裁剪截取到的图片,只复制图片左边一半
        QPixmap pix = ui->stackedWidget_matrix->grab();
        QPixmap pixleft = pix.copy(0,0,ui->stackedWidget_matrix->width()/2,ui->stackedWidget_matrix->height());
        m_label->setPixmap(pixleft);  //捕获当前界面并绘制到label上
        m_label->show();


        QLabel *m_label1 = new QLabel(ui->stackedWidget_matrix);
        m_label1->resize(QSize(ui->stackedWidget_matrix->width()/2,ui->stackedWidget_matrix->height()));
        m_label1->setAttribute(Qt::WA_DeleteOnClose);

        //裁剪截取到的图片,只复制图片右边边一半
        QPixmap pixright = pix.copy(ui->stackedWidget_matrix->width()/2,0,ui->stackedWidget_matrix->width()/2,ui->stackedWidget_matrix->height());
        m_label1->setPixmap(pixright);  //捕获当前界面并绘制到label上
        m_label1->show();


        //左边图片向左移动
        QPropertyAnimation *animation1 = new QPropertyAnimation(m_label,"geometry");
        animation1->setDuration(1500);  //设置动画时间为1.5秒
        animation1->setStartValue(QRect(0,0,ui->stackedWidget_matrix->width()/2,ui->stackedWidget_matrix->height()));
        animation1->setEndValue(QRect(-ui->stackedWidget_matrix->width()*2,0,ui->stackedWidget_matrix->width()/2,ui->stackedWidget_matrix->height()));
        animation1->setEasingCurve(QEasingCurve::InCubic);   //设置速度曲线(先慢后快)

        //右边图片向右移动
        QPropertyAnimation *animation2 = new QPropertyAnimation(m_label1,"geometry");
        animation2->setDuration(1500);  //设置动画时间为1.5秒
        animation2->setStartValue(QRect(ui->stackedWidget_matrix->width()/2,0,ui->stackedWidget_matrix->width()/2,ui->stackedWidget_matrix->height()));
        animation2->setEndValue(QRect(ui->stackedWidget_matrix->width()*2,0,ui->stackedWidget_matrix->width()/2,ui->stackedWidget_matrix->height()));
        animation2->setEasingCurve(QEasingCurve::InCubic);   //设置速度曲线(先慢后快)

        QParallelAnimationGroup *group = new QParallelAnimationGroup;  //并行动画容器
        group->addAnimation(animation1);		//添加动画
        group->addAnimation(animation2);
        group->start(QAbstractAnimation::DeleteWhenStopped);
        ui->stackedWidget_matrix->setCurrentIndex(m_currentIndex);
        //把label置顶显示
        m_label->raise();
        m_label1->raise();
        connect(group, &QParallelAnimationGroup::finished, this, [=](){m_label->close();m_label1->close();}); //关闭动画完成后再退出软件
    }
    #endif

四、更新一版stackedWidget界面切换的简单动画效果,原地址:https://www.jb51.net/article/254239.htm

1.函数实现

.h文件中添加

public Q_SLOTS:
    void onslotBtnPre();	//翻到上一页
    void onslotBtnNext();	//翻到下一页
private:
    bool m_bDonghua = false;
    int NextIndex = 0;
    QStackedWidget *inputOutputSettingStackedWidget;

.cpp文件中添加

void InputOutputSettingsWidget::initData()
{
    inputOutputSettingStackedWidget = new QStackedWidget(this);
    inputOutputSettingStackedWidget->setObjectName("inputOutputSettingStackedWidget");
    QWidget *networkSetupWidget = new QWidget(inputOutputSettingStackedWidget);
    QWidget *videoSetupWidget = new QWidget(inputOutputSettingStackedWidget);
    QWidget *audioSetupWidget = new QWidget(inputOutputSettingStackedWidget);
    QWidget *osdSetupWidget = new QWidget(inputOutputSettingStackedWidget);
    QWidget *kvmSetupWidget = new QWidget(inputOutputSettingStackedWidget);
    QWidget *baseMapSetupWidget = new QWidget(inputOutputSettingStackedWidget);
    QWidget *advancedSetupWidget = new QWidget(inputOutputSettingStackedWidget);
    inputOutputSettingStackedWidget->addWidget(networkSetupWidget);
    inputOutputSettingStackedWidget->addWidget(videoSetupWidget);
    inputOutputSettingStackedWidget->addWidget(audioSetupWidget);
    inputOutputSettingStackedWidget->addWidget(osdSetupWidget);
    inputOutputSettingStackedWidget->addWidget(kvmSetupWidget);
    inputOutputSettingStackedWidget->addWidget(baseMapSetupWidget);
    inputOutputSettingStackedWidget->addWidget(advancedSetupWidget);
    inputOutputSettingStackedWidget->setCurrentIndex(0);
    for (int i = 0; i < 7; i++){
        QPushButton *but = new QPushButton(this);
        but->setProperty("Type", "InputConfigurationBut");
        but->setFixedHeight(25);
        but->setMinimumWidth(70);
        topRightButList.append(but);
    }
    topRightButList.at(0)->setText(tr("网络设置"));
    topRightButList.at(1)->setText(tr("视频设置"));
    topRightButList.at(2)->setText(tr("音频设置"));
    topRightButList.at(3)->setText(tr("OSD台标"));
    topRightButList.at(4)->setText(tr("KVM设置"));
    topRightButList.at(5)->setText(tr("底图设置"));
    topRightButList.at(6)->setText(tr("高级功能"));
    foreach (QPushButton *but, topRightButList) {
        connect(but, &QPushButton::clicked, this, &InputOutputSettingsWidget::onBarBtnClick);
    }
}
void InputOutputSettingsWidget::onBarBtnClick()
{
	if(but == topRightButList.at(0)){
        qDebug()<< "网络设置";
        NextIndex = 0;
        pageTurningMode();
    }
    else if(but == topRightButList.at(1)){
        qDebug()<< "视频设置";
        NextIndex = 1;
        pageTurningMode();
    }
    else if(but == topRightButList.at(2)){
        qDebug()<< "音频设置";
        NextIndex = 2;
        pageTurningMode();
    }
    else if(but == topRightButList.at(3)){
        qDebug()<< "OSD台标";
        NextIndex = 3;
        pageTurningMode();
    }
    else if(but == topRightButList.at(4)){
        qDebug()<< "KVM设置";
        NextIndex = 4;
        pageTurningMode();
    }
    else if(but == topRightButList.at(5)){
        qDebug()<< "底图设置";
        NextIndex = 5;
        pageTurningMode();
    }
    else if(but == topRightButList.at(6)){
        qDebug()<< "高级功能";
        NextIndex = 6;
        pageTurningMode();
    }
}
void InputOutputSettingsWidget::onslotBtnPre()
{
    if (m_bDonghua) {
        return;
    }
    m_bDonghua = true;
    int currentIndex = inputOutputSettingStackedWidget->currentIndex();
    int windowWidth = inputOutputSettingStackedWidget->widget(currentIndex)->width();
    int windowHieght = inputOutputSettingStackedWidget->widget(currentIndex)->height();
    if (currentIndex == 0) {
        return;
    }
    inputOutputSettingStackedWidget->setCurrentIndex(NextIndex);
    inputOutputSettingStackedWidget->widget(currentIndex)->show();
    QPropertyAnimation* animation1;
    QPropertyAnimation* animation2;
    QParallelAnimationGroup* group = new QParallelAnimationGroup;
    animation1 = new QPropertyAnimation(inputOutputSettingStackedWidget->widget(currentIndex), "geometry");
    animation1->setDuration(500);
    animation1->setStartValue(QRect(0, 0, windowWidth, windowHieght));
    animation1->setEndValue(QRect(windowWidth, 0, windowWidth, windowHieght));

    animation2 = new QPropertyAnimation(inputOutputSettingStackedWidget->widget(NextIndex), "geometry");
    animation2->setDuration(500);
    animation2->setStartValue(QRect(-windowWidth, 0, windowWidth, windowHieght));
    animation2->setEndValue(QRect(0, 0, windowWidth, windowHieght));

    group->addAnimation(animation1);
    group->addAnimation(animation2);
    group->start(QAbstractAnimation::DeleteWhenStopped);
    group->setProperty("widget", QVariant::fromValue(inputOutputSettingStackedWidget->widget(currentIndex)));
    connect(group, &QParallelAnimationGroup::finished, this, &InputOutputSettingsWidget::onAnimationFinished);
}

void InputOutputSettingsWidget::onslotBtnNext()
{
    if (m_bDonghua) {
        return;
    }
    m_bDonghua = true;
    int currentIndex = inputOutputSettingStackedWidget->currentIndex();
    int windowWidth = inputOutputSettingStackedWidget->widget(currentIndex)->width();
    int windowHieght = inputOutputSettingStackedWidget->widget(currentIndex)->height();
    if (currentIndex >= inputOutputSettingStackedWidget->count()) {
        return;
    }
    inputOutputSettingStackedWidget->setCurrentIndex(NextIndex);
    inputOutputSettingStackedWidget->widget(currentIndex)->show();
    QPropertyAnimation* animation1;
    QPropertyAnimation* animation2;
    QParallelAnimationGroup* group = new QParallelAnimationGroup;
    animation1 = new QPropertyAnimation(inputOutputSettingStackedWidget->widget(currentIndex), "geometry");
    animation1->setDuration(500);
    animation1->setStartValue(QRect(0, 0, windowWidth, windowHieght));
    animation1->setEndValue(QRect(-windowWidth, 0, windowWidth, windowHieght));

    animation2 = new QPropertyAnimation(inputOutputSettingStackedWidget->widget(NextIndex), "geometry");
    animation2->setDuration(500);
    animation2->setStartValue(QRect(windowWidth, 0, windowWidth, windowHieght));
    animation2->setEndValue(QRect(0, 0, windowWidth, windowHieght));

    group->addAnimation(animation1);
    group->addAnimation(animation2);
    group->start(QAbstractAnimation::DeleteWhenStopped);
    group->setProperty("widget", QVariant::fromValue(inputOutputSettingStackedWidget->widget(currentIndex)));
    connect(group, &QParallelAnimationGroup::finished, this, &InputOutputSettingsWidget::onAnimationFinished);
}

2.效果展示

请添加图片描述

总结

简单记录下我使用过的动画效果,方便之后需要时查看。
  • 17
    点赞
  • 123
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
QML中可以通过使用动画来实现各种特效,包括进场动画。其中,百叶窗特效是一种常见的进场动画,可以让界面元素以一定的节奏和方式出现。下面是一个简单的实现示例: ```qml import QtQuick 2.0 Rectangle { width: 300 height: 300 color: "white" Repeater { model: 5 Image { id: image source: "image.png" width: parent.width / 5 height: parent.height x: index * width clip: true transform: Scale { id: scale origin.x: width / 2 origin.y: height / 2 xScale: 1 yScale: 0 } Behavior on transform { PropertyAnimation { duration: 500 easing.type: Easing.InOutQuad } } } } Component.onCompleted: { for (var i = 0; i < repeater.count; i++) { var image = repeater.itemAt(i); image.scale.y = 1; } } } ``` 在这个示例中,我们使用了一个Repeater来创建了5个相同的Image元素,每个元素的宽度都是父元素宽度的1/5。我们将这些元素放置在一起,然后通过使用clip属性来将它们裁剪成相同大小。接着,我们为每个元素添加了一个缩放变换,初始时y轴的比例为0,这样它们就会“收缩”起来。最后,在组件完成时,我们将每个元素的缩放比例y设置为1,这样它们就会“展开”出现。 在这个示例中,我们使用了PropertyAnimation来控制变换的动画效果。该动画持续500ms,并且使用了Easing.InOutQuad缓动函数,使它看起来更加平滑。你可以根据需要对这些参数进行调整,以达到更好的效果。 总体来说,百叶窗特效是一种简单而又实用的进场动画,可以轻松地让你的应用程序变得更加生动有趣。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值