调用QAbstractAnimation :: start()时,QPropertyAnimation不会立即运行

时间:2016-07-09 18:13:44

标签: c++ qt qt4

我正在尝试使用QStackedWidgets在Qt Creator中使用Qt 4.8.6制作一个简单的多页面小部件。目标是在进度条达到完整值后让QLabelQProgressBar逐渐消失。我认为实现这一目标的最佳方法是使用QGraphicsOpacityEffectQPropertyAnimation串联,如下所示。

void MainWindow::AnimateStartScreen()
{
    //QSound::play("./Audio/THX-DeepNote-48Khz.wav");
    sleep(5);

    logoEffect = new QGraphicsOpacityEffect();
    logoAnimation = new QPropertyAnimation(logoEffect, "opacity");
    ui->startLogo->setGraphicsEffect(logoEffect);
    logoAnimation->setDuration(2000);
    logoAnimation->setStartValue(1);
    logoAnimation->setEndValue(0);
    logoAnimation->start();

    progressBarEffect = new QGraphicsOpacityEffect();
    progressBarAnimation = new QPropertyAnimation(progressBarEffect, "opacity");
    ui->startProgressBar->setGraphicsEffect(progressBarEffect);
    progressBarAnimation->setDuration(2000);
    progressBarAnimation->setStartValue(1);
    progressBarAnimation->setEndValue(0);
    progressBarAnimation->start();

    sleep(3);
}

然后由main方法调用:

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;

    w.HideTitleBar();
    w.CenterWidget();
    //QMainWindow::showFullScreen();
    w.show();
    w.IncrementProgressbar();
    w.AnimateStartScreen();
    w.ChangePageTo(1);

    return a.exec();
}

这就是问题所在。我希望在更改页面之前完成此动画:

void MainWindow::ChangePageTo(int page)
{
    ui->stackedWidget->setCurrentIndex(page);
}

有没有办法可以延迟页面更改,直到我的动画完成?当我注释掉页面更改时,动画似乎甚至没有开始,直到QApplication::exec()方法调用main,这显然是等待8秒(两个睡眠调用的组合),而不是在调用QAbstractAnimation::start()之前的5秒延迟。

我相信发生的事情是sleep(3)行正在停止运行GUI的线程,因此将动画的开始延迟三秒钟。当睡眠调用完成后,我想知道动画是否尝试继续,但由于页面更改,快速过渡没有明显的效果。

如何在不停止动画运行的线程的情况下延迟3秒?或者是否有任何其他建议会产生同样的效果?

2 个答案:

答案 0 :(得分:1)

  

我相信正在发生的事情是sleep(3)行正在停止运行GUI的线程

几乎可以肯定。要运行动画,您需要保持消息队列运行,在您发布的代码中,在后续调用a.exec()之前不会发生。

如果你真的需要阻止MainWindow::AnimateStartScreen的执行,直到动画完成,那么或许更好的想法就是用...替换对sleep(3)的调用。

while (progressBarAnimation->state() != QAbstractAnimation::Stopped)
  QCoreApplication::processEvents();

(尽管您可能需要使用标记传递给QCoreApplication::processEvents以获得所需的精确行为。)

答案 1 :(得分:1)

使用下一个模式进行非阻塞等待(而非睡眠):

QEventLoop loop;
connect( progressBarAnimation, &QAbstractAnimaion::finished, &loop, &QEventLoop::quit );
loop.exec();