无意中发现一篇博客讲了QT事件源代码,看了半天看不懂,所以就加一下注释再理解一下
(1)第一步:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MouseEvent w;
w.show();
return a.exec();
}
(2)第二步: 调用QGuiApplication的exec() ,是QApplication的父类
int QApplication::exec()
{
return QGuiApplication::exec();
}
(3)第三步:调用QCoreApplication的exec() ,是QGuiApplication的父类
int QGuiApplication::exec()
{
#ifndef QT_NO_ACCESSIBILITY
QAccessible::setRootObject(qApp); 设置全APP里cation为根对象
#endif
return QCoreApplication::exec();
}
(4)第四步:调用QEventLoop的exec()
int QCoreApplication::exec()
{
if (!QCoreApplicationPrivate::checkInstance("exec")) //如果在执行状态,则返回错误
return -1;
QThreadData *threadData = self->d_func()->threadData; //返回主线程的线程id
if (threadData != QThreadData::current()) { //当前线程和主线程的id不一样。则报错显示当前线程类的不是从主线程调用的
qWarning("%s::exec: Must be called from the main thread", self->metaObject()->className());
return -1;
}
if (!threadData->eventLoops.isEmpty()) { //判断当前事件循环不是空的,则报错
qWarning("QCoreApplication::exec: The event loop is already running");
return -1;
}
threadData->quitNow = false; //设置主线程的立即停止位false
QEventLoop eventLoop; //定义新的事件循环
self->d_func()->in_exec = true; //将当前的事件循环的(正在执行置为true),这样当再次执行改程序时,可判断当前正在执行状态中,
便可在第一个if中返回
self->d_func()->aboutToQuitEmitted = false; //将事件循环的将要停止发射设置为false,使得可以发射信号
int returnCode =
eventLoop.exec(); //定义返回字显示的颜色格式
threadData->quitNow = false; //当事件循环执行完后,再次将立即停止定义为false
if (self) {
self->d_func()->in_exec = false;//将执行状态设置为false,使得后续的事件可以继续执行
if (!self->d_func()->aboutToQuitEmitted) //如果此状态为false,则重新发送消息停止的消息
emit self->aboutToQuit(QPrivateSignal());
self->d_func()->aboutToQuitEmitted = true; //将状态停止发送状态置为true
sendPostedEvents(0, QEvent::DeferredDelete); //投递延时delete的事件
}
return returnCode;
}
(5)第五步:进入事件循环
int QEventLoop::exec(ProcessEventsFlags flags)
{
Q_D(QEventLoop); // 不知道啥作用
//we need to protect from race condition with QThread::exit 获取当前主线程的锁
QMutexLocker locker(&static_cast
(QObjectPrivate::get(d->threadData->thread))->mutex);
if (d->threadData->quitNow)//如果线程的状态为停止,则返回
return -1;
if (d->inExec) {判断主线程已在执行状态,则返回
qWarning("QEventLoop::exec: instance %p has already called exec()", this);
return -1;
}
struct LoopReference { //一个结构体:
QEventLoopPrivate *d; //定义事件循环指针
QMutexLocker &locker; //定义一个锁
bool exceptionCaught; // 定义
LoopReference(QEventLoopPrivate *d, QMutexLocker &locker) : d(d), locker(locker), exceptionCaught(true)
{
d->inExec = true; // 将事件循环状态设置为正在执行中
d->exit = false; // 将事件停止设置为false
++d->threadData->loopLevel; //将当前事件的优先级加1
d->threadData->eventLoops.push(d->q_func()); // 将事件加入线程事件循环中
locker.unlock(); // 解锁
}
~LoopReference()
{
if (exceptionCaught) {
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");
}
locker.relock(); //重新锁住
QEventLoop *eventLoop = d->threadData->eventLoops.pop(); // 将最后一个事件pop出来
Q_ASSERT_X(eventLoop == d->q_func(), "QEventLoop::exec()", "internal error"); //
Q_UNUSED(eventLoop); // --release warning
d->inExec = false; //将正在执行的标志位设置为false
--d->threadData->loopLevel; //将其事件个数(还是什么)减1????????????????
}
};
LoopReference ref(d, locker);
// remove posted quit events when entering a new event loop
QCoreApplication *app = QCoreApplication::instance();
if (app && app->thread() == thread()) //判断app的线程和事件线程是否为一个线程
QCoreApplication::removePostedEvents(app, QEvent::Quit); 删除时间投递,并将其设置为停止
while (!d->exit) //如果没有退出
processEvents(flags | WaitForMoreEvents | EventLoopExec);
ref.exceptionCaught = false;
return d->returnCode;
}
(6)调用QCoreApplication的processEvents进行事件分发
(7)调用notify进行分发
bool QCoreApplication::notify(QObject *receiver, QEvent *event)
{
Q_D(QCoreApplication);
// no events are delivered after ~QCoreApplication() has started
if (QCoreApplicationPrivate::is_app_closing)
return true;
if (receiver == 0) { // serious error
qWarning("QCoreApplication::notify: Unexpected null receiver");
return true;
}
#ifndef QT_NO_DEBUG
d->checkReceiverThread(receiver);
#endif
return receiver->isWidgetType() ? false : d->notify_helper(receiver, event);
}