Jason C
Jason C

Reputation: 40406

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.

Upvotes: 1

Views: 4043

Answers (2)

Nejat
Nejat

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

Randy the Dev
Randy the Dev

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

Related Questions