当程序执行exec()后,程序进入事件循环
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
...
return a.exec(); //调用QApplication:exec()函数,进入消息循环
}
进入QApplication::exec(),程序继续调用QCoreApplication::exec();
int QApplication::exec()
{
...
return QCoreApplication::exec(); //继续调用QCoreApplication:exec()函数
}
进入QCoreApplication::exec(),程序继续调用QEventLoop::exec()函数;
int QCoreApplication::exec()
{
...
int returnCode = eventLoop.exec(); //继续调用QEventLoop::exec();
...
return returnCode;
}
进入QEvent::exec(),程序继续调用 QEventLoop::processEvents(ProcessEventsFlags flags)函数
int QEventLoop::exec(ProcessEventsFlags flags)
{
...
try {
while (!d->exit)
processEvents(flags | WaitForMoreEvents | EventLoopExec); //继续调用QEventLoop::processEvents(ProcessEventsFlags flags)函数
} catch (...) {
...
}
return d->returnCode;
}
进入QEventLoop::processEvents(ProcessEventsFlags flags),继续调用QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags)
bool QEventLoop::processEvents(ProcessEventsFlags flags)
{
...
return d->threadData->eventDispatcher->processEvents(flags); //继续调用QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags)函数
}
进入QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags),首先通过PeekMessage获得获得系统消息,然后调用TranslateMessage与DispatchMessage翻译并分发消息
bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags)
{
...
if (!filterEvent(&msg)) {
TranslateMessage(&msg); //翻译消息
DispatchMessage(&msg); //分发消息
}
...
return retVal;
}
继续来看qt的widget是怎样响应系统的消息的
QWidget::QWidget(QWidgetPrivate &dd, QWidget* parent, Qt::WindowFlags f)
: QObject(dd, 0), QPaintDevice()
{
...
d->init(parent, f);
...
}
void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f)
{
...
if ((f & Qt::WindowType_Mask) == Qt::Desktop)
q->create();
...
}
void QWidget::create(WId window, bool initializeWindow, bool destroyOldWindow)
{
...
d->create_sys(window, initializeWindow, destroyOldWindow);
...
}
void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyOldWindow)
{
...
QString windowClassName = qt_reg_winclass(q);
...
}
const QString qt_reg_winclass(QWidget *w) // register window class
{
...
wc.lpfnWndProc = (WNDPROC)QtWndProc; //窗口过程
...
}
extern "C" LRESULT QT_WIN_CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
...
result = widget->translateMouseEvent(msg); // mouse event
...
}
bool QETWidget::translateMouseEvent(const MSG &msg)
{
...
res = QApplicationPrivate::sendMouseEvent(target, &e, alienWidget, this, &qt_button_down, qt_last_mouse_receiver);
...
}
bool QApplicationPrivate::sendMouseEvent(QWidget *receiver, QMouseEvent *event,
QWidget *alienWidget, QWidget *nativeWidget,
QWidget **buttonDown, QPointer<QWidget> &lastMouseReceiver,
bool spontaneous)
{
...
if (spontaneous)
result = QApplication::sendSpontaneousEvent(receiver, event);
else
result = QApplication::sendEvent(receiver, event);
...
return result;
}
inline bool QCoreApplication::sendEvent(QObject *receiver, QEvent *event)
{
if (event) event->spont = false; return self ? self->notifyInternal(receiver, event) : false;
}
bool QCoreApplication::notifyInternal(QObject *receiver, QEvent *event)
{
...
QT_TRY {
returnValue = notify(receiver, event);
} QT_CATCH (...) {
--threadData->loopLevel;
QT_RETHROW;
}
...
return returnValue;
}
bool QCoreApplication::notify(QObject *receiver, QEvent *event)
{
...
return receiver->isWidgetType() ? false : d->notify_helper(receiver, event);
}
bool QCoreApplicationPrivate::notify_helper(QObject *receiver, QEvent * event)
{
// send to all application event filters
if (sendThroughApplicationEventFilters(receiver, event)) //qApplication的eventfilter()
return true;
// send to all receiver event filters
if (sendThroughObjectEventFilters(receiver, event)) //接收widget的eventfilter()
return true;
// deliver the event
return receiver->event(event); //接收widget的event()
}
bool QCoreApplicationPrivate::sendThroughApplicationEventFilters(QObject *receiver, QEvent *event)
{
if (receiver->d_func()->threadData == this->threadData) {
// application event filters are only called for objects in the GUI thread
for (int i = 0; i < eventFilters.size(); ++i) {
register QObject *obj = eventFilters.at(i);
if (!obj)
continue;
if (obj->d_func()->threadData != threadData) {
qWarning("QCoreApplication: Application event filter cannot be in a different thread.");
continue;
}
if (obj->eventFilter(receiver, event))
return true;
}
}
return false;
}
bool QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject *receiver, QEvent *event)
{
Q_Q(QCoreApplication);
if (receiver != q) {
for (int i = 0; i < receiver->d_func()->eventFilters.size(); ++i) {
register QObject *obj = receiver->d_func()->eventFilters.at(i);
if (!obj)
continue;
if (obj->d_func()->threadData != receiver->d_func()->threadData) {
qWarning("QCoreApplication: Object event filter cannot be in a different thread.");
continue;
}
if (obj->eventFilter(receiver, event))
return true;
}
}
return false;
}