2012-09-21 17 views
2

我使用QTimer順利更改標籤的尺寸:當我將鼠標懸停在一個按鈕,它應該生長緩慢,慢慢塌陷(減小它的大小,直到它自敗)當鼠標離開按鈕時。QTimer成爲每個啓動速度更快/停止

我有我的窗體類兩個定時器:

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

問題:一切工程進展順利,在第一,標籤慢慢打開和關閉。但是,如果這樣做了幾次,它就會開始每次更快更快地改變大小(就像計時器的間隔越來越小,但顯然不是這樣)。最終,經過了幾個開口/關閉它纔開始立即增加它的大小最多綁定,當我將鼠標懸停在該按鈕,立即崩潰零大小的鼠標去從按鈕離開時。

這可能是什麼原因?

+0

我們可以看到'compactHorizo​​ntally(QString的)'方法,它的相應尺寸「收縮機」的方法?我有一個預感,它不是'QTimer',而是與大小調整邏輯有關。而且,'QPropertyAnimation'就是爲這個目的而設計的,它讓生活變得更容易。 – cmannett85

+1

@ cmannett85,更新了問題。我做它而學習的目的,這就是爲什麼我執行它自己 – SingerOfTheFall

+0

哪個類提供'mouseEntered'信號? – UmNyobe

回答

2

我建議的事件等待處理,並隨時間而增加排隊事件的數量。也許是因爲一個事件在兩個計時器事件之間或者由於程序的其他部分而沒有完全處理。

你爲什麼不使用只有一個定時器?您可以更進一步,只需使用插槽來更改大小事件。的其他插槽只是有用於改變變化的是什麼類型:

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 
} 
+0

謝謝,改變1計時器幫助。雖然這很有趣,但我沒有想到它可以像這樣...... – SingerOfTheFall

+0

我同意。我也需要在qt事件上做作業,但對我來說這仍然是一個灰色地帶。 – UmNyobe

2

據代碼,QTimertimeout()信號連接多次相同的時隙,和多個連接的意思是當所述信號被髮射,該插槽也將被稱爲倍數倍,這看起來好像計時器正在加速。

要避免這種情況,你可以使連接獨特的搭配:

connect(&oTimer, SIGNAL(timeout()), this, SLOT(increaseHSize()), Qt::UniqueConnection); 
+0

嗯..這就是答案! –