定时器的源码分析
startTimer返回定时器的ID,在定时时间到了后,收到一个QTimerEvent,并覆盖虚函数timerEvent进行处理,该QTimerEvent包括了定时器ID
看QTimer的源码就明白了:
QObject::startTimer()
{
if (Q_UNLIKELY(!d->threadData->eventDispatcher.load())) {
qWarning("QObject::startTimer: Timers can only be used with threads started with QThread");
return 0;
}
if (Q_UNLIKELY(thread() != QThread::currentThread())) {
qWarning("QObject::startTimer: Timers cannot be started from another thread");
return 0;
}
// 调用对象关联线程的eventDispatcher来注册定时器,killTimer中是unregisterTimer
int timerId = d->threadData->eventDispatcher.load()->registerTimer(interval, timerType, this);
if (!d->extraData)
d->extraData = new QObjectPrivate::ExtraData;
d->extraData->runningTimers.append(timerId);
return timerId;
}
event dispatcher维护每个QObject对象关联的定时器的列表,再看registerTimer的源码:
void QEventDispatcherWin32::registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object)
{
if (timerId < 1 || interval < 0 || !object) {
qWarning("QEventDispatcherWin32::registerTimer: invalid arguments");
return;
} else if (object->thread() != thread() || thread() != QThread::currentThread()) {
// 又判断是不是跟event dispatcher同一线程

本文深入分析了QTimer的源码,探讨了定时器ID的生成及其在多线程环境中的使用。强调了在多线程中使用QTimer时,必须在同一线程启动和停止定时器以避免错误。同时,介绍了如何在子线程中创建和使用定时器,并将其产生的数据传递到主线程。

414

被折叠的 条评论
为什么被折叠?



