2016-03-02 56 views
0

在一個賦值中,我們應該使用C++和qt來顯示一系列對按鈕的顏色變化,每種顏色都會根據特定的輸入持續可變的時間量。教授建議使用QTimer singleshot來完成這個任務,在一定的時間之後調用某個時隙。使用C++控制動畫之間時間間隔的方法qt

我試圖通過循環播放動畫列表並創建一系列單色光標,每次通過顏色變化的長度增加等待時間。但是,動畫上次的實際時長與指定的時間有很大差異。

我的懷疑是造成singleshots和線程的性質的循環擾亂了singleshot定時器。有沒有辦法做到可靠的時間動畫,而不會潛入多線程的混亂?

如果沒有,我將如何以多線程的方式做到這一點,而不必在線程周圍完全重構我的代碼?謝謝!

+0

除非任務的其他部分需要線程,否則我不認爲需要這些線程。創建單點定時器。過了這段時間後,會更改按鈕的顏色,然後再創建另一個單拍定時器。重複。 –

回答

0

但是,動畫上次的實際時間長度與指定時間有很大差異。

如果沒有看到您的代碼,我假設您設置了一個時間陣列,並且您期望他們何時會觸發是錯誤的,因爲它是時間的累積,而不是時間本身。如果您在連接超時的插槽內下一次呼叫,則會發生這種情況。

下面是一個MCVE證明:

class MyClass : public QObject 
{  
public: 
    MyClass(); 

    void Start() 
    { 
     UpdateButton(0); 
    } 

    void UpdateButton(int delayIdx); 

    void TimedOut(int delay) 
    { 
     qDebug("Timed Out %d", delay); 
    } 

private: 
    QList<int> m_delayList; 
}; 

MyClass::MyClass() 
    : QObject(NULL) 
{ 
    m_delayList.push_back(3000); // 3 seconds 
    m_delayList.push_back(3000); 
    m_delayList.push_back(5000); 
} 

void MyClass::UpdateButton(int delayIdx) 
{ 
    if(delayIdx == m_delayList.count()) 
     return; 

    QTimer* pTimer = new QTimer(this); 
    pTimer->setSingleShot(true); 

    int delay = m_delayList[delayIdx++]; 
    connect(pTimer, &QTimer::timeout, [=](){ 

     TimedOut(delay); 
     UpdateButton(delayIdx); // use of recursion 
     pTimer->deleteLater(); 

    }); 
    pTimer->start(delay); 
} 

int main(int argc, char *argv[]) 
{ 
    QApplication a(argc, argv); 
    MyClass cls; 
    cls.Start();    
    return a.exec(); 
} 

所以,在這個例子中,類有延遲的列表。可能會出現前兩個會同時觸發(3000毫秒後),但是當我們運行時,第一個將在3秒後觸發,第二個在6秒後觸發,第三個在11秒後觸發,因爲每個連續的定時器都在前一個一個人開了槍。