Search code examples
c++winapiwindows-7timerqt4

Changing Qt's timer resolution on Windows


I have an application, written with Qt 4.8, that uses Qt's timer facilities to trigger periodic events at regular intervals (via QObject::startTimer(), with events posted to the owning QThread's message queue). Qt sets up timers on Windows by ultimately calling the Windows API function SetTimer.

The default resolution on Windows is 15.6ms. I need a period of 20ms +/- 0.5ms. However, when I specify 20ms, I am actually getting 31.2ms (+/- 0.02ms). When I specify 10ms (just for kicks), I am getting 15.6ms. This is all consistent with the default resolution. I need the resolution to be some factor of 19.5-20.5 (e.g. 0.5, 1, 2, 4, 5, 10, even 20).

I tried using timeBeginPeriod/timeEndPeriod, which reported success, but had no effect - I think this only applies to winmm timers and not SetTimer.

Qt timers are at the mercy of the underlying timer resolution for the platform, so I do have to go over its head.

Is there some way I can set the resolution of SetTimer? I'm OK with making Windows-specific API calls. I'm also OK with doing it globally, even if it comes down to a registry hack. The application is running on a dedicated Windows 7 machine, and system-wide negative effects of changing the timer resolution globally are inconsequential.


Solution

  • From the Qt documentation about QObject::startTimer(int interval, Qt::TimerType timerType = Qt::CoarseTimer) :

    Note that QTimer's accuracy depends on the underlying operating system and hardware. The timerType argument allows you to customize the accuracy of the timer. See Qt::TimerType for information on the different timer types. Most platforms support an accuracy of 20 milliseconds; some provide more. If Qt is unable to deliver the requested number of timer events, it will silently discard some.

    I think that you can set timer type to Qt::PreciseTimer. On Windows, Qt will use Windows's Multimedia timer facility (if available) for this type which has a resolution of 1 millisecond.