Qt中事件分发源代码剖析
来源:互联网 发布:java代码的基本格式 编辑:程序博客网 时间:2024/06/06 16:57
Qt中事件分发源代码剖析
Qt中事件传递顺序:
在一个应该程序中,会进入一个事件循环,接受系统产生的事件,并且进行分发,这些都是在exec中进行的。下面举例说明:
1)首先看看下面一段示例代码:
int main(int argc, char *argv[]){ QApplication a(argc, argv); MouseEvent w; w.show(); return a.exec();}
2)a.exec进入事件循环,调用的是QApplication::exec();
int QApplication::exec(){ return QGuiApplication::exec();}
3)QApplication::exec()调用的是QGuiApplication::exec();
int QGuiApplication::exec(){#ifndef QT_NO_ACCESSIBILITY QAccessible::setRootObject(qApp);#endif return QCoreApplication::exec();}
4)QGuiApplication::exec()调用的是QCoreApplication::exec();
int QCoreApplication::exec(){ if (!QCoreApplicationPrivate::checkInstance("exec")) return -1; QThreadData *threadData = self->d_func()->threadData; if (threadData != QThreadData::current()) { 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; 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(QPrivateSignal()); self->d_func()->aboutToQuitEmitted = true; sendPostedEvents(0, QEvent::DeferredDelete); } return returnCode;}
5)QCoreApplication::exec()调用eventLoop.exec()进行事件循环;
int QEventLoop::exec(ProcessEventsFlags flags){ Q_D(QEventLoop); //we need to protect from race condition with QThread::exit QMutexLocker locker(&static_cast<QThreadPrivate *>(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; ++d->threadData->loopLevel; 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(); Q_ASSERT_X(eventLoop == d->q_func(), "QEventLoop::exec()", "internal error"); Q_UNUSED(eventLoop); // --release warning d->inExec = false; --d->threadData->loopLevel; } }; LoopReference ref(d, locker); // remove posted quit events when entering a new event loop QCoreApplication *app = QCoreApplication::instance(); if (app && app->thread() == thread()) QCoreApplication::removePostedEvents(app, QEvent::Quit); while (!d->exit) processEvents(flags | WaitForMoreEvents | EventLoopExec); ref.exceptionCaught = false; return d->returnCode;}
6)eventLoop.exec()调用QCoreApplication的processEvents进行事件分发;
7)调用notify进行分发
QCoreApplication::sendEvent、QCoreApplication::postEvent和QCoreApplication::sendPostedEvents都调用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);}
8)notify调用notify_helper进行事件分发;
bool QCoreApplicationPrivate::notify_helper(QObject *receiver, QEvent * event){ // send to all application event filters if (sendThroughApplicationEventFilters(receiver, event)) return true; // send to all receiver event filters if (sendThroughObjectEventFilters(receiver, event)) return true; // deliver the event return receiver->event(event);}
9)从上面第8步的代码可以看出事件传递
传递的顺序是:首先传递给全局的事件过滤器,再传递给目标对象的事件过滤器,最终传递给目标对象。
1 0
- Qt中事件分发源代码剖析
- Qt中事件分发源代码剖析
- 剖析Qt 事件的产生、分发、接受、处理流程
- Qt事件分发
- 事件分发机制深入剖析
- Android 事件分发深入剖析
- view事件分发源代码详解
- Qt的事件分发过程
- Android MotionEvent事件分发机制源码剖析
- Android中事件分发机制
- Java中事件分发线程
- android中事件分发机制
- Android中事件分发机制
- Android中事件分发机制
- Android中事件分发流程图
- Android事件分发机制源码剖析(1)——Activity对点击事件的分发过程
- Android事件分发机制源码剖析(2)—顶层View对点击事件的分发过程
- opencv中camshiftdemo源代码剖析
- QuartusII_13.0下载及破解工具地址
- cocos2dx3.0图像拼接(像素匹配)
- install hadoop2.2 trouble shooting
- 郑州大学2014 ACM省赛选拔赛 1001-画直线
- 进程是否采用3d指令的判断
- Qt中事件分发源代码剖析
- 03-06组合与聚合_编程
- camel重要网址收集
- ffmpeg简化编译
- 摘记—Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Cha
- 程序员总结:帮助你早些明白一些道理
- 多线程消息队列框架的设计(很好很实用的设计思想)
- 【笔记】专注
- java计算器 图形用户界面 升级版v2.0 (限制位数显示+四舍五入的处理)