QCoreApplication类exec()方法分析
忙到现在才有时间做一些简单的代码分析,过不了多久就要睡觉了,又是忙碌的一天,每天如此,好像轻闲下来,但是真正闲下来的时候,又会去想着忙点多好。人就是这样,总是很难满足于现状。
今天,先对exec()函数的后半部分进行分析:
QEventLoop eventLoop;
self->d_func()->in_exec = true;
self->d_func()->aboutToQuitEmitted = false;
int returnCode = eventLoop.exec();
threadData->quitNow = false;
if (self) {
self->d_func()->in_exec = false;
if (!self->d_func()->aboutToQuitEmitted)
emit self->aboutToQuit();
self->d_func()->aboutToQuitEmitted = true;
sendPostedEvents(0, QEvent::DeferredDelete);
}
该方法在程序退出之前是不返回的,eventLoop.exec()的调用会让程序进入一个事件循环,直到程序结束。
进入QEventLoop中的exec方法:
Q_D(QEventLoop);
if (d->threadData->quitNow)
return -1;
if (d->inExec) {
qWarning("QEventLoop::exec: instance %p has already called exec()", this);
return -1;
}
d->inExec = true;
d->exit = false;
++d->threadData->loopLevel;
d->threadData->eventLoops.push(this);
首先将事件类对象压入线程结构体中。
// remove posted quit events when entering a new event loop
QCoreApplication *app = QCoreApplication::instance();
if (app && app->thread() == thread())
QCoreApplication::removePostedEvents(app, QEvent::Quit);
英文的注释说的已经很清楚了。
#if defined(QT_NO_EXCEPTIONS)
while (!d->exit)
processEvents(flags | WaitForMoreEvents | EventLoopExec);
#else
try {
while (!d->exit)
processEvents(flags | WaitForMoreEvents | EventLoopExec);
} catch (...) {
qWarning("Qt has caught an exception thrown from an event handler. Throwing/n"
"exceptions from an event handler is not supported in Qt. You must/n"
"reimplement QApplication::notify() and catch all exceptions there./n");
// copied from below
QEventLoop *eventLoop = d->threadData->eventLoops.pop();
Q_ASSERT_X(eventLoop == this, "QEventLoop::exec()", "internal error");
Q_UNUSED(eventLoop); // --release warning
d->inExec = false;
--d->threadData->loopLevel;
throw;
}
#endif
在此调用事件循环不同平台下的事件分派器的processEvent方法进行事件分析。
当出现异常时,将当前事件放弃掉。
// copied above
QEventLoop *eventLoop = d->threadData->eventLoops.pop();
Q_ASSERT_X(eventLoop == this, "QEventLoop::exec()", "internal error");
Q_UNUSED(eventLoop); // --release warning
d->inExec = false;
--d->threadData->loopLevel;
return d->returnCode;
在此,事件循环退出。
好了,今天就只能分析到这些,电脑快没电了,关于QApplication的分析,需要明天进行了。
2009年11月3日星期二 00:00