Reputation: 333
I am trying to make a simple multi-page widget with QStackedWidgets
in Qt Creator with Qt 4.8.6
. The goal is to have a QLabel
and QProgressBar
fade away after the progress bar reaches full value. I thought the best way to achieve this was using QGraphicsOpacityEffect
and QPropertyAnimation
in tandem as seen below.
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);
}
Which is then called by the main
method:
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();
}
Here lies the problem. I want this animation to finish before I change the page like so:
void MainWindow::ChangePageTo(int page)
{
ui->stackedWidget->setCurrentIndex(page);
}
Is there a way I can delay page change until my animation is complete? When I comment out the page change, the animation doesn't seem to even start until QApplication::exec()
is called in my main
method, evident by a 8 second waiting period (the combination of both sleep calls), rather than a 5 second delay before QAbstractAnimation::start()
is called.
I believe what is happening is that the sleep(3)
line is stopping the thread in which the GUI is running on, hence delaying the start of the animation for three seconds. When the sleep call has completed, I wonder if the animation tries to continue, but because of the page change,there is just no visible effect from the quick transition.
How can I make a 3 second delay without stopping the thread that the animation is running off of? Or are there any other suggestions that will produce the same effect?
Upvotes: 0
Views: 803
Reputation: 8994
Use next pattern for non-blocking waiting (instead of sleep):
QEventLoop loop;
connect( progressBarAnimation, &QAbstractAnimaion::finished, &loop, &QEventLoop::quit );
loop.exec();
Upvotes: 1
Reputation: 12879
I believe what is happening is that the sleep(3) line is stopping the thread in which the GUI is running on
Almost certainly. For the animation to run you need to keep the message queue running which, in the code you've posted, won't occur until the subsequent call to a.exec()
.
If you really need to block execution of MainWindow::AnimateStartScreen
until the animation has completed then perhaps a better idea would be to replace the call to sleep(3)
with...
while (progressBarAnimation->state() != QAbstractAnimation::Stopped)
QCoreApplication::processEvents();
(Although you might have to play about with the flags pass to QCoreApplication::processEvents
to get the precise behaviour you require.)
Upvotes: 1