int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
QCoreApplication::QCoreApplication(int &argc, char **argv
#ifndef Q_QDOC
, int _internal
#endif
)
#ifdef QT_NO_QOBJECT
: d_ptr(new QCoreApplicationPrivate(argc, argv, _internal))
#else
: QObject(*new QCoreApplicationPrivate(argc, argv, _internal))
#endif
{
d_func()->q_ptr = this;
d_func()->init();
#ifndef QT_NO_QOBJECT
QCoreApplicationPrivate::eventDispatcher->startingUp();
#endif
}
void QCoreApplicationPrivate::init()
{
#ifndef QT_NO_QOBJECT
// use the event dispatcher created by the app programmer (if any)
Q_ASSERT(!eventDispatcher);
//检查用户是否自行创建了事件调度器,没有则创建---------------------------------------------------
eventDispatcher = threadData->eventDispatcher.loadRelaxed();
//创建事件调度器-----------------------------------------------------------------
// otherwise we create one
if (!eventDispatcher)
createEventDispatcher();
Q_ASSERT(eventDispatcher);
//事件调度器是否有父对象,没有则把q指针作为父对象---------------------------------------
//movetothread,将事件调度器的槽函数放在子线程中,构造函数仍在主线程---------------------------------------
if (!eventDispatcher->parent()) {
eventDispatcher->moveToThread(threadData->thread.loadAcquire());
eventDispatcher->setParent(q);
}
//重置当前线程的事件调度器,处于准备状态------------------------------------------------------
threadData->eventDispatcher = eventDispatcher;
eventDispatcherReady();
#endif
//处理命令行参数------------------------------------------------------------------------------
processCommandLineArguments();
//启动hook------------------------------------------------------------------------------
qt_call_pre_routines();
qt_startup_hook();
#ifndef QT_BOOTSTRAPPED
if (Q_UNLIKELY(qtHookData[QHooks::Startup]))
reinterpret_cast<QHooks::StartupCallback>(qtHookData[QHooks::Startup])();
#endif
#ifndef QT_NO_QOBJECT
is_app_running = true; // No longer starting up.
#endif
}
void QCoreApplicationPrivate::createEventDispatcher()
{
//获取当前线程的线程数据-----------------------------------------------------------------------
Q_Q(QCoreApplication);
QThreadData *data = QThreadData::current();
Q_ASSERT(!data->hasEventDispatcher());
//调用QThreadPrivate::createEventDispatcher创建事件调度器并设置其父对象----------------------------
eventDispatcher = data->createEventDispatcher();
eventDispatcher->setParent(q);
}
QAbstractEventDispatcher *QThreadData::createEventDispatcher()
{
//调用QThreadPrivate::createEventDispatcher创建-------------------------------------
QAbstractEventDispatcher *ed = QThreadPrivate::createEventDispatcher(this);
eventDispatcher.storeRelease(ed);
//创建完后启动----------------------------------------------------------------------------
ed->startingUp();
return ed;
}
QAbstractEventDispatcher *QThreadPrivate::createEventDispatcher(QThreadData *data)
{
Q_UNUSED(data);
#ifndef Q_OS_WINRT
return new QEventDispatcherWin32;
#else
return new QEventDispatcherWinRT;
#endif
}
int QCoreApplication::exec()
{
//检查QCoreApplication自身实例是否存在
if (!QCoreApplicationPrivate::checkInstance("exec"))
return -1;
//获取实例d指针的线程数据,检查QCoreApplication是否位于主线程中
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()->execCleanup();
return returnCode;
}
QEventLoop::exec()将创建的事件循环器添加到主线程中,为主线程的主循环器,负责gui的操作事件
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.loadAcquire()))->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.storeRelease(false);
++d->threadData->loopLevel;//循环器级别调至1级
d->threadData->eventLoops.push(d->q_func());//将事件循环器添加到所在线程的事件循环器存储容器中
locker.unlock();
}
~LoopReference()
{//*****有省略********* }
//*****有省略*********
};
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);//如果是则清除程序退出的post事件
//*****有省略*********
//如果没有退出,执行进程事件
while (!d->exit.loadAcquire())
processEvents(flags | WaitForMoreEvents | EventLoopExec);
ref.exceptionCaught = false;
return d->returnCode.loadRelaxed();
}
QEventLoop::processEvents进程事件中检查事件调度器(eventdispatcherwin32)是否存在,如果不存在则退出,存在则调用eventDispatcher的processEvents处理程序所有事件。
bool QEventLoop::processEvents(ProcessEventsFlags flags)
{
Q_D(QEventLoop);
if (!d->threadData->hasEventDispatcher())
return false;
return d->threadData->eventDispatcher.loadRelaxed()->processEvents(flags);
}
调度器eventdispatcherwin32作用是qt系统和windows系统进行数据交互。
bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags)
{
Q_D(QEventDispatcherWin32);
//检查private对象是否创建了隐藏窗口,如果没有则进行创建,并唤醒
if (!d->internalHwnd) {
createInternalHwnd();
wakeUp(); // trigger a call to sendPostedEvents()
}
d->interrupt.storeRelaxed(false);
emit awake();//发送已创建信号
sendPostedEvents();
bool canWait;
bool retVal = false;
do {
DWORD waitRet = 0;
DWORD nCount = 0;
HANDLE *pHandles = nullptr;
//检查windows事件通知激活事件的状态,如果为激活状态,则获取状态的句柄
if (d->winEventNotifierActivatedEvent) {
nCount = 1;
pHandles = &d->winEventNotifierActivatedEvent;
}
QVarLengthArray<MSG> processedTimers;
while (!d->interrupt.loadRelaxed()) {
MSG msg;
bool haveMessage;
//检查用户输入事件的队列是否为空,不为空则处理第一个事件
if (!(flags & QEventLoop::ExcludeUserInputEvents) && !d->queuedUserInputEvents.isEmpty()) {
// process queued user input events
haveMessage = true;
msg = d->queuedUserInputEvents.takeFirst();
//检查socket事件的队列是否为空,不为空则处理第一个事件
} else if(!(flags & QEventLoop::ExcludeSocketNotifiers) && !d->queuedSocketEvents.isEmpty()) {
// process queued socket events
haveMessage = true;
msg = d->queuedSocketEvents.takeFirst();
//检查事件可用性,如果可用,移除后进行转化,重新加入到队列中
} else {
haveMessage = PeekMessage(&msg, 0, 0, 0, PM_REMOVE);
if (haveMessage) {
if (flags.testFlag(QEventLoop::ExcludeUserInputEvents)
&& isUserInputMessage(msg.message)) {
// queue user input events for later processing
d->queuedUserInputEvents.append(msg);
continue;
}
if ((flags & QEventLoop::ExcludeSocketNotifiers)
&& (msg.message == WM_QT_SOCKETNOTIFIER && msg.hwnd == d->internalHwnd)) {
// queue socket events for later processing
d->queuedSocketEvents.append(msg);
continue;
}
}
}
//事件无效,进行相应处理
if (!haveMessage) {
// no message - check for signalled objects
waitRet = MsgWaitForMultipleObjectsEx(nCount, pHandles, 0, QS_ALLINPUT, MWMO_ALERTABLE);
if ((haveMessage = (waitRet == WAIT_OBJECT_0 + nCount))) {
// a new message has arrived, process it
continue;
}
}
//事件有效,获取勾子事件,进行数据的传递,即事件转发给windows系统
if (haveMessage) {
if (d->internalHwnd == msg.hwnd && msg.message == WM_QT_SENDPOSTEDEVENTS) {
// Set result to 'true', if the message was sent by wakeUp().
if (msg.wParam == WMWP_QT_FROMWAKEUP)
retVal = true;
continue;
}
if (msg.message == WM_TIMER) {
// avoid live-lock by keeping track of the timers we've already sent
bool found = false;
for (int i = 0; !found && i < processedTimers.count(); ++i) {
const MSG processed = processedTimers.constData()[i];
found = (processed.wParam == msg.wParam && processed.hwnd == msg.hwnd && processed.lParam == msg.lParam);
}
if (found)
continue;
processedTimers.append(msg);
} else if (msg.message == WM_QUIT) {
if (QCoreApplication::instance())
QCoreApplication::instance()->quit();
return false;
}
if (!filterNativeEvent(QByteArrayLiteral("windows_generic_MSG"), &msg, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
} else if (waitRet - WAIT_OBJECT_0 < nCount) {
activateEventNotifiers();
} else {
// nothing todo so break
break;
}
retVal = true;
}
// still nothing - wait for message or signalled objects
canWait = (!retVal
&& !d->interrupt.loadRelaxed()
&& (flags & QEventLoop::WaitForMoreEvents));
if (canWait) {
emit aboutToBlock();
waitRet = MsgWaitForMultipleObjectsEx(nCount, pHandles, INFINITE, QS_ALLINPUT, MWMO_ALERTABLE | MWMO_INPUTAVAILABLE);
emit awake();
if (waitRet - WAIT_OBJECT_0 < nCount) {
activateEventNotifiers();
retVal = true;
}
}
} while (canWait);
return retVal;
}
QEventDispatcherWin32::createInternalHwnd()创建隐藏窗口,通过hook将事件数据转发给windows系统,同时通过qt_internal_pro获取windows系统反馈的数据信息,解包后分发处理
void QEventDispatcherWin32::createInternalHwnd()
{
Q_D(QEventDispatcherWin32);
if (d->internalHwnd)
return;
d->internalHwnd = qt_create_internal_window(this);
// setup GetMessage hook needed to drive our posted events
d->getMessageHook = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC) qt_GetMessageHook, NULL, GetCurrentThreadId());
if (Q_UNLIKELY(!d->getMessageHook)) {
int errorCode = GetLastError();
qFatal("Qt: INTERNAL ERROR: failed to install GetMessage hook: %d, %ls",
errorCode, qUtf16Printable(qt_error_string(errorCode)));
}
// start all normal timers
for (int i = 0; i < d->timerVec.count(); ++i)
d->registerTimer(d->timerVec.at(i));
}
qt_create_internal_window函数中创建了QWindowsMessageWindowClassContext 类消息上下文对象ctx,创建隐藏窗口
static HWND qt_create_internal_window(const QEventDispatcherWin32 *eventDispatcher)
{//
QWindowsMessageWindowClassContext *ctx = qWindowsMessageWindowClassContext();
if (!ctx->atom)
return 0;
HWND wnd = CreateWindow(ctx->className, // classname
ctx->className, // window name
0, // style
0, 0, 0, 0, // geometry
HWND_MESSAGE, // parent
0, // menu handle
GetModuleHandle(0), // application
0); // windows creation data.
//*****有省略**************************************
return wnd;
}
上下文类中调用回调函数qt_internal_poc,获取windows系统传给qt的msg消息,并进行解析,之后传递给qt系统进行相应的类型判断,并作出相应
QWindowsMessageWindowClassContext::QWindowsMessageWindowClassContext()
: atom(0), className(0)
{
// make sure that multiple Qt's can coexist in the same process
const QString qClassName = QStringLiteral("QEventDispatcherWin32_Internal_Widget")
+ QString::number(quintptr(qt_internal_proc));
//*****有省略**************************************
}
createInternalHwnd()中的setwindowsHookEx监听主线程的所有事件,第二个参数是函数qt_GetMessageHook,通过Windows的原生消息接口PostMessage将消息传递给创建的隐藏窗口,从而将消息传给windows系统
LRESULT QT_WIN_CALLBACK qt_GetMessageHook(int code, WPARAM wp, LPARAM lp)
{
QEventDispatcherWin32 *q = qobject_cast<QEventDispatcherWin32 *>(QAbstractEventDispatcher::instance());
Q_ASSERT(q != 0);
QEventDispatcherWin32Private *d = q->d_func();
MSG *msg = reinterpret_cast<MSG *>(lp);
static const UINT mask = inputQueueMask();
if (HIWORD(GetQueueStatus(mask)) == 0 && wp == PM_REMOVE) {
// Allow posting WM_QT_SENDPOSTEDEVENTS message.
d->wakeUps.storeRelaxed(0);
if (!(msg->hwnd == d->internalHwnd && msg->message == WM_QT_SENDPOSTEDEVENTS)) {
PostMessage(d->internalHwnd, WM_QT_SENDPOSTEDEVENTS,
WMWP_QT_TOFOREIGNLOOP, 0);
}
}
return d->getMessageHook ? CallNextHookEx(0, code, wp, lp) : 0;
}