Reputation: 40406
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.
Upvotes: 1
Views: 4043
Reputation: 32685
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.
Upvotes: 1
Reputation: 26740
It is impossible to use a resolution less than 10ms using SetTimer
. If you try to use a lower value, Windows will simply use 10ms instead.
Have you considered using the QElapsedTimer
instead? It uses Windows' high resolution performance counter by default and falls back to a less precise timer if not available.
http://qt-project.org/doc/qt-4.8/qelapsedtimer.html
Upvotes: 2