在C ++/Qt6中,我想开发一个带有动画的按钮(我想我必须使用QParallelAnimationGroup),该按钮的图标是在另一个图像中淡出的同时淡出一个图像。
以下是我想要的(与电影制作人制作):
button fade out-fade in images, demo of the effect I'm looking for
我已经开发了一个带有动画的QToolButton,它可以让按钮淡出,然后用一个新图标淡入(按顺序)。我使用了QPropertyAnimation和QSequentialAnimationGroup。
. h
#ifndef FADINGIMAGESPUSHBUTTON_H
#define FADINGIMAGESPUSHBUTTON_H
#include <QToolButton>
#include <QPropertyAnimation>
#include <QGraphicsOpacityEffect>
#include <QSequentialAnimationGroup>
class FadingImagesPushButton : public QToolButton
{
Q_OBJECT
public:
FadingImagesPushButton(QWidget *parent = nullptr, const QString & title = "", const QString & imageNormalPath = "", const QString & imageHoverPath = "");
protected:
static const int s_AnimDuration;
virtual bool event(QEvent * e) override;
void hoverEnter();
void hoverLeave();
QString m_imageNormalPath;
QString m_imageHoverPath;
int m_curTimeAnim_toHover;
int m_curTimeAnim_toNormal;
QPropertyAnimation *m_AnimNormalFadeOut;
QPropertyAnimation *m_AnimHoverFadeIn;
QPropertyAnimation *m_AnimHoverFadeOut;
QPropertyAnimation *m_AnimNormalFadeIn;
QSequentialAnimationGroup *m_toHoverAnimGroup;
QSequentialAnimationGroup *m_toNormalAnimGroup;
QGraphicsOpacityEffect *m_effect;
protected slots:
void switchToHoverImage();
void switchToNormalImage();
void deleteAndNullToHoverAnimGroup();
void deleteAndNullToNormalAnimGroup();
};
#endif // FADINGIMAGESPUSHBUTTON_H
. cpp
#include "fadingimagespushbutton.h"
#include <QEvent>
const int FadingImagesPushButton::s_AnimDuration = 800;
FadingImagesPushButton::FadingImagesPushButton(QWidget *parent,const QString & title, const QString & imageNormalPath, const QString & imageHoverPath)
:QToolButton(parent),m_imageNormalPath(imageNormalPath),m_imageHoverPath(imageHoverPath)
{
setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
setFixedSize(275,280);
setIconSize(QSize(270,240));
QFont font;
font.setPointSize(18);
setAttribute(Qt::WA_Hover);
setFont(font);
setText(title);
setIcon(QIcon(m_imageNormalPath));
m_effect = new QGraphicsOpacityEffect(this);
setGraphicsEffect(m_effect);
m_toHoverAnimGroup = nullptr;
m_toNormalAnimGroup = nullptr;
}
bool FadingImagesPushButton::event(QEvent *e)
{
switch(e->type())
{
case QEvent::HoverEnter:
hoverEnter();
return QToolButton::event(e);
case QEvent::HoverLeave:
hoverLeave();
return QToolButton::event(e);
default:
break;
}
return QToolButton::event(e);
}
void FadingImagesPushButton::hoverEnter()
{
int realDurationFadeOut = s_AnimDuration;
int realDurationFadeIn = s_AnimDuration;
if(m_toNormalAnimGroup)
{
int animGroupDuration = m_toNormalAnimGroup->currentTime();
if(animGroupDuration < s_AnimDuration)
{
realDurationFadeOut = 0;
realDurationFadeIn = animGroupDuration;
}
else
{
realDurationFadeOut = animGroupDuration - s_AnimDuration;
realDurationFadeIn = s_AnimDuration;
}
m_toNormalAnimGroup->stop();
}
if(realDurationFadeOut !=0)
{
m_AnimNormalFadeOut = new QPropertyAnimation(m_effect,"opacity");
m_AnimNormalFadeOut->setDuration(realDurationFadeOut);
m_AnimNormalFadeOut->setStartValue(1.*((float)realDurationFadeOut/(float)s_AnimDuration));
m_AnimNormalFadeOut->setEndValue(0.);
m_AnimNormalFadeOut->setEasingCurve(QEasingCurve::InBack);
}
m_AnimHoverFadeIn = new QPropertyAnimation(m_effect,"opacity");
m_AnimHoverFadeIn->setDuration(realDurationFadeIn);
m_AnimHoverFadeIn->setStartValue(1. - ((float)realDurationFadeIn/(float)s_AnimDuration));
m_AnimHoverFadeIn->setEndValue(1.);
m_AnimHoverFadeIn->setEasingCurve(QEasingCurve::InBack);
m_toHoverAnimGroup = new QSequentialAnimationGroup(this);
if(realDurationFadeOut !=0)
m_toHoverAnimGroup->addAnimation(m_AnimNormalFadeOut);
m_toHoverAnimGroup->addAnimation(m_AnimHoverFadeIn);
connect(m_toHoverAnimGroup,&QSequentialAnimationGroup::currentAnimationChanged, this, &FadingImagesPushButton::switchToHoverImage);
connect(m_toHoverAnimGroup,&QSequentialAnimationGroup::finished, this, &FadingImagesPushButton::deleteAndNullToHoverAnimGroup);
m_toHoverAnimGroup->start();
}
void FadingImagesPushButton::hoverLeave()
{
int realDurationFadeOut = s_AnimDuration;
int realDurationFadeIn = s_AnimDuration;
if(m_toHoverAnimGroup)
{
int animGroupDuration = m_toHoverAnimGroup->currentTime();
if(animGroupDuration < s_AnimDuration)
{
realDurationFadeOut = 0;
realDurationFadeIn = animGroupDuration;
}
else
{
realDurationFadeOut = animGroupDuration - s_AnimDuration;
realDurationFadeIn = s_AnimDuration;
}
m_toHoverAnimGroup->stop();
}
if(realDurationFadeOut !=0)
{
m_AnimHoverFadeOut = new QPropertyAnimation(m_effect,"opacity");
m_AnimHoverFadeOut->setDuration(realDurationFadeOut);
m_AnimHoverFadeOut->setStartValue(1.*((float)realDurationFadeOut/(float)s_AnimDuration));
m_AnimHoverFadeOut->setEndValue(0.);
m_AnimHoverFadeOut->setEasingCurve(QEasingCurve::InBack);
}
m_AnimNormalFadeIn = new QPropertyAnimation(m_effect,"opacity");
m_AnimNormalFadeIn->setDuration(realDurationFadeIn);
m_AnimNormalFadeIn->setStartValue(1.-((float)realDurationFadeIn/(float)s_AnimDuration));
m_AnimNormalFadeIn->setEndValue(1.);
m_AnimNormalFadeIn->setEasingCurve(QEasingCurve::InBack);
m_toNormalAnimGroup = new QSequentialAnimationGroup(this);
if(realDurationFadeOut !=0)
m_toNormalAnimGroup->addAnimation(m_AnimHoverFadeOut);
m_toNormalAnimGroup->addAnimation(m_AnimNormalFadeIn);
connect(m_toNormalAnimGroup,&QSequentialAnimationGroup::currentAnimationChanged, this, &FadingImagesPushButton::switchToNormalImage);
connect(m_toNormalAnimGroup,&QSequentialAnimationGroup::finished, this, &FadingImagesPushButton::deleteAndNullToNormalAnimGroup);
m_toNormalAnimGroup->start();
}
void FadingImagesPushButton::switchToHoverImage()
{
setIcon(QIcon(m_imageHoverPath));
}
void FadingImagesPushButton::switchToNormalImage()
{
setIcon(QIcon(m_imageNormalPath));
}
void FadingImagesPushButton::deleteAndNullToHoverAnimGroup()
{
m_toHoverAnimGroup = nullptr;
}
void FadingImagesPushButton::deleteAndNullToNormalAnimGroup()
{
m_toNormalAnimGroup = nullptr;
}
演示中的结果:
button fade out-fade in images, already done in sequance
1条答案
按热度按时间7z5jn7bk1#
我设法应用预期的效果,这里是代码.
注意:在我的例子中,第二个图像(悬停)是我应用在正常图像之上的一个层,但是如果你想合并两个不同的图像,只需稍微改变
applyComposition()
NB2:我们需要测试计算负载。每50毫秒应用两个QPainter可能不是最好的方法。也许用QPainter预构建16个图像会更好
.h
.cpp