id1 = startTimer(1000); // 1秒
id2 = startTimer(2000); // 2秒
id3 = startTimer(3000); // 3秒
// 另一個 QTimer
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(timerUpdate()));
timer->start(1000);
Qt 定時器基於事件循環,多定時器之間無同步保證,觸發順序取決於事件隊列投遞順序與系統調度。
startTimer(interval) 註冊定時器,返回唯一 ID。QTimerEvent,進入事件隊列。QTimer(信號槽版)本質同樣依賴事件循環,無實時性保證。// timerEvent 中
if (event->timerId() == id1) qDebug() << "timer1";
else if (event->timerId() == id2) qDebug() << "timer2";
else qDebug() << "timer3";
若 1秒、2秒、3秒定時器在 t=2s 同時到期(1秒觸發第2次、2秒觸發第1次),三個 QTimerEvent 幾乎同時入隊,**輸出順序可能是 timer1/timer2/timer3 的任意排列**。
| 誤區 | 事實 | 對策 |
|---|---|---|
| 多定時器按間隔順序執行 | 無順序保證 | 單線程用單定時器+計數器;多線程用 QThread+QWaitCondition |
| 定時器精確到毫秒 | 受事件循環擁塞影響,誤差可達數十毫秒 | 高精度需求用 QElapsedTimer+忙等或 QThread::msleep |
timerUpdate 與 timerEvent 同步 | 不同定時器獨立觸發 | 共享數據需 QMutex 保護 |
moveToThread 將 QTimer 移至工作線程,避免阻塞 UI。理解 Qt 事件驅動本質,才能寫出穩健的定時邏輯。