如何使用QpropertyAnimation制作SlideIn和SlideOut效果
How to make SlideIn and SlideOut effects using QpropertyAnimation?
我的目标
我想在这样的幻灯片中动画图像:
<< 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();
我的问题
两个滑动图像之间显示一个小间隙(约100px(:
<< Animation Direction <<
/* THIS IS HAPPENING*/
++++++++++++ --------------------
++++++++++++ --------------------
IMAGE +++++ ------ NEXT IMAGE --
++++++++++++ --------------------
++++++++++++ --------------------
<--- VIEW --------->
+++ --------------------
+++ --------------------
+++ ------ NEXT IMAGE --
+++ --------------------
+++ --------------------
<--- VIEW --------->
--------------------
--------------------
------ NEXT IMAGE --
--------------------
--------------------
<--- VIEW --------->
如何使其按预期工作,或者以其他方式实现所需的动画?
为了实现所需的动画,我建议您查看由我编写的FlatGUI
小部件库的HorizontalSlide
类。
在那里我使用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
轴滑动。然后代码对QAbstractAnimation::finished
信号作出反应,将QWidget::show
和QWidget::resize
发送到下一页。
假设您已经声明并初始化了这些变量:
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
类。
加载图像
d->currImage->setFixedSize(ui->frmSlideshow->size());
d->currImage->move(0,0);
QPixmap pixCurrImage;
pixCurrImage.load(d->currImagePath());
d->currImage->setPixmap(pixCurrImage);
d->currImage->show();
d->currImage->raise();
d->nextImage->setFixedSize(ui->frmSlideshow->size());
d->nextImage->move(ui->frmSlideshow->width(), 0); // So that
QPixmap pixNextImage; // you will not see
pixNextImage.load(d->nextImagePath()); // glitch due
d->nextImage->setPixmap(pixNextImage); // to change
d->nextImage->show();
d->nextImage->raise();
动画(感谢User6528273的帮助(
QVariantAnimation *animation = new QVariantAnimation(ui->frmSlideshow);
animation->setStartValue(0);
animation->setEndValue(ui->frmSlideshow->width());
animation->setDuration(600);
animation->start(QVariantAnimation::DeleteWhenStopped);
connect(animation, SIGNAL(valueChanged(QVariant)),
this, SLOT(onValueChanged(QVariant)));
SLOT-onValueChanged((
void onValueChanged(const QVariant &value)
{
int n = -value.toInt();
int m = ui->frmSlideshow->width() + n;
d->currImage->move(n, 0);
d->nextImage->move(m, 0);
this->repaint();
}
/** ui->frmSlideshow is the frame, on which images are sliding **/
相关文章:
- 函数中堆分配的效果与缺少堆分配的情况
- 如何改变c++应用程序的视觉效果
- unique_ptr:在分配之前调用 reset 有什么效果
- 将参数传递为"const"的奇怪效果
- 如何为对象生成滚动效果?
- 为什么const_cast和static_cast常量引用没有效果?
- 在 Cocos2dx 中初始化粒子效果后的警告 - "libpng warning: iCCP: known incorrect sRGB profile"
- 在 3ds Max 中更新进度条后,环境和效果 UI 不刷新
- 为什么指标有时效果很好,有时效果不佳?写下霍夫曼代码
- 变量 BitMask 在函数 CeilLog2 中的实际效果是什么?
- 如何调整ICU的UnicodeString::caseCompare(或获得相同的效果)
- 曼哈顿距离比曼哈顿距离+线性冲突效果更好
- 在C++中使用克隆方法实现多晶型效果
- 将多个效果与 libSox 链接并读取输出数据的正确方法
- 哪种返回值的方法在C++中效果更快?
- 如何摆脱逗号运算符的这个错误右操作数没有效果( wunsued 值)?
- 作为副本传递的 std::move()'d 变量的效果是什么?
- 如何在 direct2d 中使用随其窗口重新缩放的效果绘制图像
- 为什么通过指针赋值常量没有效果?
- 如何在 Qml 沙德效果中将统一浮点数组传递给片段着色器?