2

を使用しQTimerてラベルのサイズをスムーズに変更しています。マウスをボタンの上に置くとラベルはゆっくりと大きくなり、マウスがボタンから離れるとゆっくりと折りたたまれます (消えるまでサイズが小さくなります)。

フォームのクラスに 2 つのタイマーがあります。

QTimer oTimer, cTimer;//oTimer for expanding, cTimer for collapsing

フォームのコンストラクターで、タイマーの値を設定し、ボタンmouseOvermouseOutシグナルをフォームのスロットに接続しています。

oTimer.setInterval( 25 );
cTimer.setInterval( 25 );

connect( ui.Button, 
         SIGNAL(mouseEntered(QString)), 
         this, 
         SLOT(expandHorizontally(QString)) );
connect( ui.Button, 
         SIGNAL(mouseLeft(QString)), 
         this, 
         SLOT(compactHorizontally(QString)) );

ここで、これらのスロットで、対応するタイマーをスロットに接続し、スロットのサイズを徐々に変更してから、タイマーを開始します。

void cForm::expandHorizontally(const QString & str)
{
    ui.Text->setText( str ); 
    connect( &oTimer, SIGNAL(timeout()), this, SLOT(increaseHSize()) );
    cTimer.stop();//if the label is collapsing at the moment, stop it
    disconnect( &cTimer, SIGNAL(timeout()) );
    oTimer.start();//start expanding
}

void cForm::compactHorizontally(const QString &)
{
    connect( &cTimer, SIGNAL(timeout()), this, SLOT(decreaseHSize()) );
    oTimer.stop();
    disconnect( &oTimer, SIGNAL(timeout()) );
    cTimer.start();
}

その後、ラベルはサイズの変更を開始します。

void cForm::increaseHSize()
{
    if( ui.Text->width() < 120 )
    {
        //increase the size a bit if it hasn't reached the bound yet
        ui.Text->setFixedWidth( ui.Text->width() + 10 );
    }
    else
    {
        ui.Text->setFixedWidth( 120 );//Set the desired size
        oTimer.stop();//stop the timer
        disconnect( &oTimer, SIGNAL(timeout()) );//disconnect the timer's signal
    }
}

void cForm::decreaseHSize()
{
    if( ui.Text->width() > 0 )
    {
        ui.Text->setFixedWidth( ui.Text->width() - 10 );
    }
    else
    {
        ui.Text->setFixedWidth( 0 );
        cTimer.stop();
        disconnect( &cTimer, SIGNAL(timeout()) );
    }
}

問題: 最初はすべてがスムーズに機能しますが、ラベルがゆっくりと開いたり閉じたりします。ただし、これを数回行うと、そのたびにサイズがどんどん速く変化し始めます (タイマーの間隔がどんどん小さくなっていくように、しかし明らかにそうではありません)。最終的に、数回開いたり閉じたりした後、マウスをボタンの上に置くとすぐにサイズが境界まで大きくなり始めマウスがボタンから離れるとすぐにサイズがゼロになります。

その理由は何でしょうか?

4

2 に答える 2

2

あなたのコードによると、QTimertimeout()信号は同じスロットに複数回接続されています。複数の接続は、信号が送信されるとスロットも複数回呼び出されることを意味し、タイマーが加速しているように見えます。

これを回避するには、次の方法で接続を一意にすることができます。

connect( &oTimer, SIGNAL(timeout()), this, SLOT(increaseHSize()), Qt::UniqueConnection);
于 2012-09-21T12:42:51.953 に答える
2

イベントが処理されるのを待っていて、キューに入れられたイベントの数が時間とともに増加することをお勧めします。2 つのタイマー イベント間でイベントが完全に処理されていないか、プログラムの他の部分が原因である可能性があります。

タイマーを 1 つだけ使用してみませんか。サイズ変更イベントにスロットのみを使用することで、さらに先に進むことができます。他のスロットは、変更の種類を変更するためだけにあります。

void cForm::connectStuff(){
    connect( &oTimer, SIGNAL(timeout()), this, SLOT(changeSize()) );
    connect( 
          ui.Button, 
          SIGNAL(mouseEntered(QString)), 
          this, 
          SLOT(expandHorizontally()) 
    );
    connect( 
          ui.Button, 
          SIGNAL(mouseLeft(QString)), 
          this, 
          SLOT(compactHorizontally()) 
    );
}

void cForm::expandHorizontally(){
      shouldExpand = true;
}

void cForm::compactHorizontally(){
      shouldExpand = false;
}

void cForm::changeSize(){
     if(shouldExpand)
        increaseHSize();//call the function which expand
     else
        decreaseHSize();//call the function which compact
}
于 2012-09-21T10:16:13.487 に答える