c++ - 如何使用QpropertyAnimation制作SlideIn和SlideOut效果?

标签 c++ qt

我的目标
我想为幻灯片显示中的图像设置动画,如下所示:

<< Animation Direction <<  
/* THIS IS EXPECTATION */  

++++++++++++++++++++--------------------
++++++++++++++++++++--------------------
+++ CURR IMAGE +++++------ NEXT IMAGE --
++++++++++++++++++++--------------------
++++++++++++++++++++--------------------
<--- VIEW --------->

++++++++++++--------------------
++++++++++++--------------------
 IMAGE +++++------ NEXT IMAGE --
++++++++++++--------------------
++++++++++++--------------------
<--- VIEW --------->

--------------------
--------------------
------ NEXT IMAGE --
--------------------
--------------------
<--- VIEW --------->
我尝试过的
我使用QPropertyAnimation 的两个实例:
d->currImage      = new QLabel(ui->frmSlideshow);
d->currImage->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
d->animCurrImage  = new QPropertyAnimation(d->currImage, "geometry");

d->nextImage      = new QLabel(ui->frmSlideshow);
d->nextImage->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
d->animNextImage  = new QPropertyAnimation(d->nextImage, "geometry");

connect(d->animNextImage, SIGNAL(finished()),this, SLOT(applyBackground()));
connect(&(d->timer), SIGNAL(timeout()), this, SLOT(timer_timeout()));
d->timer.start(1500);
超时时,请执行以下操作:
QPixmap pixCurrImage;
pixCurrImage.load(d->currImagePath());
d->currImage->setPixmap(pixCurrImage);

QPixmap pixNextImage;
pixNextImage.load(d->nextImagePath());
d->nextImage->setPixmap(pixNextImage);

d->currImage->show();
d->currImage->raise();
d->currImage->setFixedSize(ui->frmSlideshow->size());

d->nextImage->show();
d->nextImage->raise();
d->nextImage->setFixedSize(ui->frmSlideshow->size());

d->animCurrImage->setDuration(500);
d->animCurrImage->setStartValue(QRect(0, 0, ui->frmSlideshow->width(), ui->frmSlideshow->height()));
d->animCurrImage->setEndValue(QRect(-1*ui->frmSlideshow->width(), 0, ui->frmSlideshow->width(), ui->frmSlideshow->height()));

d->animNextImage->setDuration(500);
d->animNextImage->setStartValue(QRect(2*ui->frmSlideshow->width(), 0, ui->frmSlideshow->width(), ui->frmSlideshow->height()));
d->animNextImage->setEndValue(QRect(0, 0, ui->frmSlideshow->width(), ui->frmSlideshow->height()));

QParallelAnimationGroup * group = new QParallelAnimationGroup(this);
group->addAnimation(d->animCurrImage);
group->addAnimation(d->animNextImage);
group->start();
我的问题
两个滑动图像之间都显示一个小间隙(大约100像素):
<< Animation Direction <<  
/* THIS IS HAPPENING*/  

++++++++++++   --------------------
++++++++++++   --------------------
 IMAGE +++++   ------ NEXT IMAGE --
++++++++++++   --------------------
++++++++++++   --------------------
<--- VIEW --------->

+++   --------------------
+++   --------------------
+++   ------ NEXT IMAGE --
+++   --------------------
+++   --------------------
<--- VIEW --------->

--------------------
--------------------
------ NEXT IMAGE --
--------------------
--------------------
<--- VIEW --------->
如何使其按预期工作,或以其他方式实现所需的动画?

最佳答案

为了获得所需的动画,我建议您看一下我编写的小部件HorizontalSlide库的 FlatGUI 类。
在那里,我使用 QVariantAnimation 来创建滑动效果。以下是有关动画的HorizontalSlide的基本部分:

void HorizontalSlide::start(bool slideLeft, int speed)
{
    QVariantAnimation *animation = new QVariantAnimation(this);

    m_slideLeft = slideLeft;

    m_labCurrent->show();
    m_labNext->show();

    animation->setStartValue(m_slideLeft ? 0 : m_width);
    animation->setEndValue(m_slideLeft ? m_width : 0);
    animation->setDuration(speed);
    animation->start(QVariantAnimation::DeleteWhenStopped);

    connect(animation, &QVariantAnimation::valueChanged,
            this, &HorizontalSlide::onValueChanged);
    connect(animation, &QVariantAnimation::finished,
            this, &HorizontalSlide::onAnimationFinished);
}

void HorizontalSlide::onValueChanged(const QVariant &value)
{
    int n = -value.toInt(), m = m_width + n;

    if (m_slideLeft) {
        m_labCurrent->move(n, 0);
        m_labNext->move(m, 0);
    } else {
        m_labCurrent->move(m, 0);
        m_labNext->move(n, 0);
    }

    m_parentWidget->repaint();
}

void HorizontalSlide::onAnimationFinished()
{
    delete m_labCurrent;
    delete m_labNext;

    m_nextPage->show();
    m_nextPage->resize(m_parentWidget->size());

    deleteLater();
    finished();
}
我使用 QVariantAnimation::valueChanged 信号 QWidget::move 小部件的快照来沿x -axis滑动。然后,代码对下一页的 QAbstractAnimation::finished QWidget::show QWidget::resize 信号使用react。
假设您已声明和初始化了这些变量:
QWidgetList pages;  
currentIndex(-1),
nextIndex(-1),
busy(false)
您可以在这样的方法中使用HorizontalSlide:
void slideToPage(int n, int speed) {
    if (busy
        || pages.isEmpty()
        || (currentIndex < 0)
        || (n == currentIndex)
        || (speed < 0))
        return;

    auto *transition = new HorizontalSlide(this);

    busy = true;

    transition->setCurrentPage(pages.at(currentIndex));
    transition->setNextPage(pages.at(n));
    transition->start(n > currentIndex, speed);

    connect(transition, &HorizontalSlide::finished,
                     [this, transition](){
        currentIndex = pages.indexOf(transition->nextPage());
        busy = false;

        currentIndexChanged(currentIndex, pages.count());
        currentPageChanged(pages.at(currentIndex)->windowTitle());
    });
}
您不妨将库添加到项目中并使用其 SlideView 类。

关于c++ - 如何使用QpropertyAnimation制作SlideIn和SlideOut效果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64085128/

相关文章:

c++ - 是否可以通过编程方式更改 USB<-> 串行转换器的 'BM' 延迟选项?

c++ - 如何在windows上安装<QtCharts>

c++ - C++ 中的异常类

c++ - Poco::Data 绑定(bind)到一个 std::array 参数

c++ - 创建与输入同名的文件

c++ - 多线程中的构造函数和析构函数

c++ - 不能从父级调用子级中的函数

Qt Phonon 打开原始音频数据文件

qt - QML:通过父引用引用根窗口是不可靠的

c++ - 在QT5中,如何在子菜单项的点击事件上打开新窗口?