2016-07-09 10 views
0

Qt 4.8.6のQt CreatorでQStackedWidgetsの単純な複数ページウィジェットを作成しようとしています。プログレスバーが最大値に達した後で、QLabelQProgressBarが消えることが目標です。これを達成する最善の方法は、下記のようにQGraphicsOpacityEffectQPropertyAnimationを縦に並べて使用していると考えました。その後、mainメソッドによって呼び出されQAbstractAnimation :: start()が呼び出されたときにQPropertyAnimationがすぐに実行されない

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); 
} 

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); 
} 

は私のアニメーションが完了するまで、私は、ページの変更を遅らせることができます方法はありますか?私がページ変更をコメントアウトすると、が私のmainメソッドで呼び出されるまでアニメーションが開始されないように見えますが、QAbstractAnimation::start()の前に5秒の遅延ではなく、8秒の待ち時間(両方のスリープ呼び出しの組み合わせ)が呼び出されます。

私は、sleep(3)行がGUIが実行されているスレッドを停止しているため、アニメーションの開始を3秒間遅らせると考えています。スリープコールが完了すると、アニメーションが続行しようとしているのだろうかと思うが、ページが変更されているため、早い遷移から目に見える効果はない。

アニメーションが実行されているスレッドを停止せずに3秒間遅延させるにはどうすればよいですか?あるいは同じ効果を生み出す他の提案はありますか?

答えて

1

私は何が起こっていることは、睡眠は(3)ラインはGUIがほぼ確実

上で実行されているスレッドを停止していることであると信じています。アニメーションを実行するには、メッセージキューを実行したままにしておく必要があります。投稿したコードでは、その後の呼び出しではa.exec()が呼び出されます。

あなたは本当にアニメーションが完了するまで、おそらく良いアイデアがでsleep(3)への呼び出しを置き換えることであろうMainWindow::AnimateStartScreenの実行をブロックする必要がある場合は...

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

(あなたがおよそプレイしているかもしれませんが、フラグで必要な正確な動作を得るためにQCoreApplication::processEventsに渡す)

+0

このような無限ループは、オーバーヘッドが大きく、不要なCPU使用量です。 –

+0

どのようにして無限ループですか? 'QCoreApplication :: processEvents'は、現在キューに入れられたイベントを処理してから復帰します。タイムアウトが必要な場合は、タイムアウトを指定できるオーバーロードを呼び出します(したがって、フラグの指定などに関する私のコメント)。 –

+0

私はあなたがイベントを待っているのではなく、すべてのステップが 'processEvents'の呼び出しを行うことを意味します。それはかなり重い操作です。そのようなもののための 'QEventLoop'クラスがあります。私の答えをチェックしてください。 –

1

使用非ブロッキング)の代わりに睡眠(待機しているため、次のパターン:。

QEventLoop loop; 
connect(progressBarAnimation, &QAbstractAnimaion::finished, &loop, &QEventLoop::quit); 
loop.exec(); 
関連する問題