QTimer's pitfall process and qtimer's pitfall Process
Recently, I encountered a problem that QTimer was set to 10 ms and the result did not take effect. It was a headache. I checked it for almost a day and finally found out why?
The following describes how to use QTimer:
M_delayHideTimer: the object of QTimer.
Connect (& m_delayHideTimer, SIGNAL (timeout (), this, SLOT (slotHideMenu (); // when the time is exhausted, the system will respond to the subsequent callback function.
M_delayHideTimer.setInterval (100) // reset the timer time.
M_delayHideTimer.stop (); // stop the timer.
M_delayHideTimer.start (50); // start the timer
For other usage, check QT asssistant and you will know more about it:
Why 10 ms precision does not take effect:
Let's talk about the source code of QT, which describes the implementation of Timer:
In the qeventdispatcher_win.cpp file of QT, there is a function as follows:
Void QEventDispatcherWin32Private: registerTimer (WinTimerInfo * t)
{
Q_ASSERT (internalHwnd );
Q_Q (QEventDispatcherWin32 );
Int OK = 0;
CalculateNextTimeout (t, qt_msectime ());
Uint interval = t-> interval;
If (interval = 0u ){
// Optimization for single-shot-zero-timer
QCoreApplication: postEvent (q, new QZeroTimerEvent (t-> timerId ));
OK = 1;
} Else if (interval <20u | t-> timerType = Qt: PreciseTimer) & qtimeSetEvent ){
OK = t-> fastTimerId = qtimeSetEvent (interval, 1, qt_fast_timer_proc, (DWORD_PTR) t,
TIME_CALLBACK_FUNCTION | TIME_PERIODIC | TIME_KILL_SYNCHRONOUS );
}
If (OK = 0 ){
// User normal timers for (Very) CoarseTimers, or if no more multimedia timers available
OK = SetTimer (internalHwnd, t-> timerId, interval, 0 );
}
If (OK = 0)
QErrnoWarning ("QEventDispatcherWin32: registerTimer: Failed to create a timer ");
}
The source code shows that a few things have been done: If the timer precision is less than 20 ms, it will enter the qtimeSetEvent function; otherwise, it will go to SetTimer in winapi.
QtimeSetEvent:
QtimeSetEvent = (ptimeSetEvent) QSystemLibrary: resolve (QLatin1String ("winmm"), "timeSetEvent ");
QtimeKillEvent = (ptimeKillEvent) QSystemLibrary: resolve (QLatin1String ("winmm"), "timeKillEvent ");
Winmm is an interface for windows multimedia applications and a dynamic library. To respond to windows multimedia timer.
This timer should not be used unless it has a very high precision, because win will allocate a separate thread to this top timer and call timeSetEvent several times, so it needs to call timeKillEvent several times, the corresponding ID must be the same.
I checked various forums in China and foreign countries and found that the same thread cannot exceed 16, and that the same process cannot exceed 16. In short, more than 16 do not take effect, try not to write a timer with a precision less than 20 ms here, just in case. Follow-up
For this research, we need to update and modify the bug first...