2017-05-01 5 views
2

QWidgetのインスタンスを初期化し、レイアウト内に配置してアニメーションを呼び出すコードを用意しました。そのすべてがループ内で起こっています。 QThread :: usleep()を完全に無視して、アニメーションを描画するそれぞれの繰り返しの問題に遭遇しました。レイアウトをきれいにして所望の結果を得ることができる方法がありますか?QTのウィジェットを再ペーストする

double randomTestArray[numOfPoints]; 
double fMin = 0; 
double fMax = 20; 
srand(time(NULL)); 
for(int p = 0 ; p < 100 ; p++) 
{ 
    Equalizer * eq = new Equalizer(); 
    ui->verticalLayout->addWidget(eq); 
    for(int i = 0 ; i < numOfPoints ; i++) 
    { 
     randomTestArray[i] = fMin + (double)rand() * (fMax - fMin)/RAND_MAX; 
    }    
    eq->setChunk(&randomTestArray[0] , &startArray[0]); 
    ui->verticalLayout->removeWidget(eq); 
    delete eq; 
    QThread::usleep(1000); 
} 

アニメーションは、setChunk()メソッドでQPropertyAnimationとpaintEvent()を使用して実行されます。これ以上のコードが必要な場合は、私に通知してください。イコライザークラスの破壊を追加

void Equalizer::setChunk(double *chunk, int * startYArr) 
{ 

if(*startYArr == -1) 
{ 
    for(int i = 0 ; i < 24 ; i++) 
    { 
     *(startYArr + i) = 150; 
    } 
} 

int xCoordinateArray[24]; 
int yCoordinateArray[24]; 

for(int i = 0 ; i < 24 ; i++) 
{ 
    yCoordinateArray[i] = *(chunk + i) * 5; 
    xCoordinateArray[i] = 100 + i*25; 
} 

cout << "Chunk initialized" << endl; 
cout << "Start Coordinates : " << endl; 
for(int i = 0 ; i < 24 ; i++) 
{ 
    cout << startYArr[i] << endl; 
} 
cout << "End Coordinates : " << endl; 

for(int i = 0 ; i < 24 ; i++) 
{ 
    cout << yCoordinateArray[i] << endl; 
} 

QPropertyAnimation *animation = new QPropertyAnimation(this , "nrect"); 
animation->setDuration(2000); 
animation->setStartValue(QRect(xCoordinateArray[0] , *(startYArr + 0) , 10 , 10)); 
animation->setEndValue(QRect(xCoordinateArray[0] , 150 - yCoordinateArray[0] , 10 , 10)); 
animation->start(); 
connect(animation, &QPropertyAnimation::valueChanged , [=](){update();}); 

QPropertyAnimation *animation2 = new QPropertyAnimation(this , "nrect2"); 
animation2->setDuration(2000); 
animation2->setStartValue(QRect(xCoordinateArray[1] , *(startYArr + 1), 10 , 10)); 
animation2->setEndValue(QRect(xCoordinateArray[1] , 150 - yCoordinateArray[1] , 10 , 10)); 
animation2->start(); 
connect(animation2, &QPropertyAnimation::valueChanged , [=](){update();}); 

QPropertyAnimation *animation3 = new QPropertyAnimation(this , "nrect3"); 
animation3->setDuration(2000); 
animation3->setStartValue(QRect(xCoordinateArray[2] , *(startYArr +2) , 10 , 10)); 
animation3->setEndValue(QRect(xCoordinateArray[2] , 150 - yCoordinateArray[2] , 10 , 10)); 
animation3->start(); 
connect(animation3, &QPropertyAnimation::valueChanged , [=](){update();}); 
................................ 
for(int i = 0; i < 24 ; i++) 
{ 
    *(startYArr + i) = yCoordinateArray[i]; 
} 


void Equalizer::paintEvent(QPaintEvent *event) 
{ 
Q_UNUSED(event); 

QRect ellipse(mRect); 
QPainter painter(this); 
painter.setBrush(Qt::red); 
painter.drawEllipse(ellipse); 

QRect ellipse2(mRect2); 
painter.setBrush(Qt::red); 
painter.drawEllipse(ellipse2); 

QRect ellipse3(mRect3); 
painter.setBrush(Qt::red); 
painter.drawEllipse(ellipse3); 
............................. 

試み溶液:

eq->setChunk(&randomTestArray[0] , &startArray[0]); 
QCoreApplication::processEvents(); 
ui->verticalLayout->removeWidget(eq); 
QThread::usleep(1000); 
+0

"for(int p = 0; p <1; p ++)" - 本当ですか?また、 'Equalizer'インスタンスを作成し、それをレイアウトに追加し、' setChunk'を呼び出して、レイアウトから削除し、 'Qt'イベントループに戻らずにすべて削除します。私は[MCVE]を提供する必要があると思います。 –

+0

「Qtイベントループに戻る」とはどういう意味ですか? –

+0

'Qt'はイベントベースです。 'QObject'派生クラスのインスタンスに対して関数を呼び出すと、通常、それらのオブジェクトに1つ以上のイベントがポストされます。これらのイベントを処理するには、イベントループを実行する必要があります。 –

答えて

0

通常Qtは定期painting operationsすぎを回避するために画面を更新する(QWidget::updateによってトリガ)そのイベント・システムを使用します。 for -loop内の画面をメインイベントループに戻すことなく更新したいので、デフォルトの方法は機能しません。別の解決策が考えられます。

  1. 手動イベントを処理:あなたは(QPropertyAnimationから来る)すべての新しいイベントを処理する代わりにQThread::usleepの全体の待機時間の間、繰り返しQCoreApplication::processEventsを呼び出す必要があります。 Equalizerオブジェクトを削除してから削除する前に、イベントを処理することをお勧めします。

  2. フォースは、すぐに画面を再描画するには: あなたはすぐにpaintEventを呼び出すなる、QWidget::repaintを呼び出すことで、すぐに画面を再描画するためにはQtを強制することができます。
    このオプションは、QPropertyAnimationと組み合わせてうまく機能しません。 for -loop(とusleep関数呼び出し)を外し、定期的にいくつかのアクションを実行するためにQTimerオブジェクトを使用します。定期的に更新する

  3. 使用タイマーイベント。

オプション3は、Qtなどのイベントベースのシステムで使用するのに適したソリューションです。

+0

私はこれらのアプローチをすべて試しましたが、それでもループの後にのみペイントを開始します。質問の末尾に追加しました –

+0

オプション3には 'for'ループが含まれていません。したがって、イベントループの後にアニメーションが開始することは不可能です。 – m7913d

+0

私はあなたが 'QPropertyAnimation'を使用していたという事実を見落としました。したがって私は最初のアプローチを更新しました。オプション3が私の推奨する解決方法であることに注意してください。 – m7913d

関連する問題