Qt 左移逐渐消失效果

发布于:2025-07-29 ⋅ 阅读:(17) ⋅ 点赞:(0)

 左移逐渐消失效果

        本文介绍了一个Qt窗口关闭动画类XYCloseAnimationWidget的实现。该类通过组合多个QPropertyAnimation实现图片左移消失的动画效果:1)背景图片逐渐缩短宽度的主动画;2)图片位置微调的辅助动画;3)垂直线条伸缩的装饰动画。动画总时长为350毫秒,采用透明无边框窗口,通过重写paintEvent实现绘制。动画结束后自动关闭窗口,并提供isAnimationRunning方法检测动画状态。

#include "xycloseanimationwidget.h"
#include <QPainter>
#include <QTimer>

XYCloseAnimationWidget::XYCloseAnimationWidget(QWidget *parent)
    : QWidget(parent)
{
    setAttribute(Qt::WA_TranslucentBackground, true);
    setWindowFlags(Qt::FramelessWindowHint);

    pixAnimation = new QPropertyAnimation(this, "pixLen");
    pixAnimation->setLoopCount(1);
    pixAnimation->setDuration(350);

    pixPosXAnimation = new QPropertyAnimation(this, "pixPosX");
    pixPosXAnimation->setLoopCount(1);
    pixPosXAnimation->setDuration(80);

    lineRiseAnimation = new QPropertyAnimation(this, "lineLen");
    lineRiseAnimation->setLoopCount(1);
    lineRiseAnimation->setDuration(200);

    linedeAnimation = new QPropertyAnimation(this, "lineLen");
    linedeAnimation->setLoopCount(1);
    linedeAnimation->setDuration(200);

    animationGroup = new QSequentialAnimationGroup(this);
    animationGroup->addAnimation(lineRiseAnimation);
    animationGroup->addAnimation(pixPosXAnimation);
    animationGroup->addAnimation(pixAnimation);
    animationGroup->addAnimation(linedeAnimation);
    connect(animationGroup, SIGNAL(finished()), this, SLOT(close()));
}

int XYCloseAnimationWidget::pixLen() const
{
    return pixleftLen;
}

void XYCloseAnimationWidget::setPixLen(int len)
{
    pixleftLen = len;
    update();
}

int XYCloseAnimationWidget::pixPosX() const
{
    return pixCurPosX;
}

void XYCloseAnimationWidget::setPixPosX(int x)
{
    pixCurPosX = x;
    update();
}

int XYCloseAnimationWidget::lineLen() const
{
    return lineLeftLen;
}

void XYCloseAnimationWidget::setLineLen(int len)
{
    lineLeftLen = len;
    update();
}

void XYCloseAnimationWidget::setBackgroundPix(const QPixmap &pix)
{
    backgroundPix = pix;
    pixleftLen = backgroundPix.width();
    resize(backgroundPix.size() + QSize(interval + 2, 0));
}

void XYCloseAnimationWidget::startAnimation()
{
    pixAnimation->setEndValue(0);
    pixPosXAnimation->setEndValue(interval);
    lineRiseAnimation->setEndValue(height());
    linedeAnimation->setEndValue(0);
    animationGroup->start();
}

void XYCloseAnimationWidget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
    painter.drawPixmap(QRect(pixCurPosX + backgroundPix.width() - pixleftLen, 0,
                             pixleftLen, backgroundPix.height()),
                       backgroundPix,
                       QRect(0, 0,
                             pixleftLen, backgroundPix.height()));

    if (lineLeftLen > 0)
    {
        painter.setPen(QColor("#9DDAE9"));
        painter.drawLine(width() - 2, (height() - lineLeftLen) / 2,
                         width() - 2, (height() + lineLeftLen) / 2);
    }

}

bool XYCloseAnimationWidget::isAnimationRunning()
{
    return animationGroup->state() == QAbstractAnimation::Running;
}


网站公告

今日签到

点亮在社区的每一天
去签到