I have to read a file that describes animations frames at constant interval. i know this interval so I used QTimer to regularly trigger an update.
The problem is, when i approximately measure the time it takes (with a stopwatch), i see an important difference between theoretical and actual times.

So i wrote an example code showing my problem : It's a shape that go around in a scene. every round it makes I decrease the framerate and display few things :
- the time it took to make a round
- the time it should have taken, regarding current frame rate
- the relative difference between these 2 times

Qt Code:
  1. #include <QApplication>
  2. #include <QtGui>
  3.  
  4.  
  5. qreal interval = 1.0 ;
  6. const qreal nbFrames = 100.0 ;
  7.  
  8.  
  9. class View : public QGraphicsView
  10. {
  11. Q_OBJECT
  12. QGraphicsScene *scene ;
  13. int timerid ;
  14. qreal angle, step, radius ;
  15. QTime t0, t1 ;
  16.  
  17. public :
  18. View(void)
  19. : scene(new QGraphicsScene),
  20. angle(0), // start angle=0°
  21. step(360.0/nbFrames), // 1 round == 852 frames
  22. radius(150.0) // circle radius
  23. {
  24. scene->setBackgroundBrush(Qt::darkBlue) ;
  25. setScene(scene) ;
  26. // draw circle path
  27. new QGraphicsEllipseItem(QRectF(-radius,-radius,2*radius,2*radius),0,scene) ;
  28. // draw shape
  29. item = new QGraphicsRectItem(QRectF(-25,-15,50,30),0,scene) ;
  30. item->setBrush(Qt::darkYellow) ;
  31. item->setPen(QPen(Qt::black)) ;
  32. // draw start point
  33. QGraphicsEllipseItem *start = new QGraphicsEllipseItem(QRectF(radius-2,-2,4,4),0,scene) ;
  34. start->setBrush(Qt::red) ;
  35. start->setPen(QPen(Qt::black)) ;
  36. // start animation
  37. t0 = QTime::currentTime() ;
  38. qDebug() << "start at" << t0.toString("hh:mm:ss.zzz") << ", interval =" << interval ;
  39. timerid = startTimer(interval) ;
  40. }
  41.  
  42. protected :
  43. void timerEvent(QTimerEvent *e)
  44. {
  45. if(angle>=360)
  46. {
  47. // compute time and restart
  48. t1 = QTime::currentTime() ;
  49. qreal theoric = 0.001*interval*nbFrames ;
  50. qreal measured = 0.001*t0.msecsTo(t1) ;
  51. qreal diff = (measured-theoric) ;
  52. qreal delta = 100*diff/measured ;
  53. qDebug() << "round time :" << measured << "s, should be" << theoric << "s (diff ="<<diff<<"("<<delta<<"%) for"<<interval<<")" ;
  54. killTimer(timerid) ;
  55. interval++ ; // decrease framerate
  56. angle = 0 ;
  57. t0 = QTime::currentTime() ;
  58. timerid = startTimer(interval) ;
  59. }
  60. else
  61. {
  62. // compute new position
  63. qreal radians = M_PI*angle/180.0 ;
  64. qreal x = radius*cos(radians) ;
  65. qreal y = radius*sin(radians) ;
  66. item->setPos(x,y) ;
  67. // step ahead
  68. angle += step ;
  69. }
  70. }
  71. } ;
  72.  
  73. int main(int argc, char** argv)
  74. {
  75. QApplication app(argc,argv) ;
  76. View view ;
  77. view.setGeometry(QRect(100,100,600,500)) ;
  78. view.show() ;
  79. return app.exec() ;
  80. }
  81.  
  82. #include "main.moc"
To copy to clipboard, switch view to plain text mode 

And here is what I obtain on my comps (one desktop and one laptop, both on XP SP3 i guess) : After an interval of 20ms, whatever interval i give, the total time of an animation is the same for a range of a dozen framerate :

Quote Originally Posted by debug
round time : 1.418 s, should be 1.4 s (diff = 0.018 ( 1.26939 %) for 14 )
round time : 1.512 s, should be 1.5 s (diff = 0.012 ( 0.793651 %) for 15
round time : 1.606 s, should be 1.6 s (diff = 0.006 ( 0.373599 %) for 16
round time : 1.715 s, should be 1.7 s (diff = 0.015 ( 0.874636 %) for 17
round time : 1.808 s, should be 1.8 s (diff = 0.008 ( 0.442478 %) for 18
round time : 1.917 s, should be 1.9 s (diff = 0.017 ( 0.886802 %) for 19
round time : 2.011 s, should be 2 s (diff = 0.011 ( 0.546992 %) for 20 )
round time : 3.149 s, should be 2.1 s (diff = 1.049 ( 33.3122 %) for 21 )
round time : 3.148 s, should be 2.2 s (diff = 0.948 ( 30.1144 %) for 22 )
round time : 3.149 s, should be 2.3 s (diff = 0.849 ( 26.9609 %) for 23 )
round time : 3.149 s, should be 2.4 s (diff = 0.749 ( 23.7853 %) for 24 )
round time : 3.149 s, should be 2.5 s (diff = 0.649 ( 20.6097 %) for 25 )
round time : 3.148 s, should be 2.6 s (diff = 0.548 ( 17.4079 %) for 26 )
round time : 3.149 s, should be 2.7 s (diff = 0.449 ( 14.2585 %) for 27 )
round time : 3.149 s, should be 2.8 s (diff = 0.349 ( 11.0829 %) for 28 )
round time : 3.149 s, should be 2.9 s (diff = 0.249 ( 7.90727 %) for 29 )
round time : 3.149 s, should be 3 s (diff = 0.149 ( 4.73166 %) for 30 )
round time : 3.149 s, should be 3.1 s (diff = 0.049 ( 1.55605 %) for 31 )
round time : 4.193 s, should be 3.2 s (diff = 0.993 ( 23.6823 %) for 32 )
round time : 4.723 s, should be 3.3 s (diff = 1.423 ( 30.1292 %) for 33 )
round time : 4.724 s, should be 3.4 s (diff = 1.324 ( 28.0271 %) for 34 )
round time : 4.723 s, should be 3.5 s (diff = 1.223 ( 25.8946 %) for 35 )
round time : 4.724 s, should be 3.6 s (diff = 1.124 ( 23.7934 %) for 36 )
round time : 4.723 s, should be 3.7 s (diff = 1.023 ( 21.66 %) for 37 )
round time : 4.723 s, should be 3.8 s (diff = 0.923 ( 19.5427 %) for 38 )
round time : 4.724 s, should be 3.9 s (diff = 0.824 ( 17.4428 %) for 39 )
round time : 4.723 s, should be 4 s (diff = 0.723 ( 15.3081 %) for 40 )
round time : 4.723 s, should be 4.1 s (diff = 0.623 ( 13.1908 %) for 41 )
round time : 4.724 s, should be 4.2 s (diff = 0.524 ( 11.0923 %) for 42 )
round time : 4.723 s, should be 4.3 s (diff = 0.423 ( 8.95617 %) for 43 )
round time : 4.724 s, should be 4.4 s (diff = 0.324 ( 6.85859 %) for 44 )
round time : 4.723 s, should be 4.5 s (diff = 0.223 ( 4.72158 %) for 45 )
round time : 4.723 s, should be 4.6 s (diff = 0.123 ( 2.60428 %) for 46 )
round time : 5.082 s, should be 4.7 s (diff = 0.382 ( 7.51673 %) for 47 )
round time : 6.298 s, should be 4.8 s (diff = 1.498 ( 23.7853 %) for 48 )
round time : 6.298 s, should be 4.9 s (diff = 1.398 ( 22.1975 %) for 49 )
round time : 6.298 s, should be 5 s (diff = 1.298 ( 20.6097 %) for 50 )
round time : 6.298 s, should be 5.1 s (diff = 1.198 ( 19.0219 %) for 51 )
round time : 6.297 s, should be 5.2 s (diff = 1.097 ( 17.421 %) for 52 )
round time : 6.298 s, should be 5.3 s (diff = 0.998 ( 15.8463 %) for 53 )
round time : 6.298 s, should be 5.4 s (diff = 0.898 ( 14.2585 %) for 54 )
round time : 6.298 s, should be 5.5 s (diff = 0.798 ( 12.6707 %) for 55 )
round time : 6.298 s, should be 5.6 s (diff = 0.698 ( 11.0829 %) for 56 )
round time : 6.298 s, should be 5.7 s (diff = 0.598 ( 9.49508 %) for 57 )
round time : 6.297 s, should be 5.8 s (diff = 0.497 ( 7.89265 %) for 58 )
round time : 6.298 s, should be 5.9 s (diff = 0.398 ( 6.31947 %) for 59 )
round time : 6.298 s, should be 6 s (diff = 0.298 ( 4.73166 %) for 60 )
round time : 6.298 s, should be 6.1 s (diff = 0.198 ( 3.14386 %) for 61 )
round time : 6.298 s, should be 6.2 s (diff = 0.098 ( 1.55605 %) for 62 )
round time : 7.545 s, should be 6.3 s (diff = 1.245 ( 16.501 %) for 63 )
round time : 7.872 s, should be 6.4 s (diff = 1.472 ( 18.6992 %) for 64 )

Unfortunately for my app i need an interval of 33ms, which is obviously one of the worse result : 30% of difference. It means that for an animation of 10s, my app will display an animation which lasts 13s.

Is it a known issue, and what are the possible alternatives ?