Начинаем изучать события например с функции resizeEvent .
Ищем причину , того кто вызывает наш resizeEvent и ему подобные функции.
По логике изменение размера происходит при визуальном действии мышкой например , когда мы растягиваем рамку виджета.
Таким образом сначала возникает событие. Это событие сначала получает операционная система (по USB каналу) , которая потом передает нашему приложению . Операционная система не знает на каком виджете находился курсор мышки, поэтому может передать только всему приложение в целом .
У нас приложение это QCoreApplication ! Это не gui , это kernel ветка исходников Qt. Тут есть qcoreevent.cpp
Тут все разработчиками популярно написано о логике событий :
Qt's main event loop(QCoreApplication::exec())fetches native
window system events from the event queue, translates them into
QEvents, andsends the translated events to \l{QObject}s.
In general, events come from the underlying window system(spontaneous() returns true), but it is also possible to manually
send events usingQCoreApplication::sendEvent()andQCoreApplication::postEvent()(spontaneous() returns false).
QObjects receive events by having their QObject::event()function
called. The function can be reimplemented in subclasses to
customize event handling andadd additional event types;
QWidget::event() is a notable example. By default, events are
dispatched to event handlers like QObject::timerEvent()andQWidget::mouseMoveEvent(). QObject::installEventFilter()allows an
object to intercept events destined foranother object.
The basic QEvent contains only an event type parameter andan
"accept" flag. The accept flag set with accept(), andcleared
with ignore(). It is set by default, but don't rely on thisas
subclasses may choose to clear it in their constructor.
Subclasses of QEvent contain additional parameters that describe
the particular event.
QObject::event(), QObject::installEventFilter(), QWidget::event(), CoreApplication::sendEvent(),
Ищем QCoreApplication::exec(..), там суть такая ,что в нем запускается eventLoop.exec() , который и мониторит входящие события, там по сути две строчки:
intQCoreApplication::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;
intreturnCode = 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);
}
returnreturnCode;
}
eventLoop.exec()в qeventloop.cppв свою очередь вызывает processEvents(..)
intQEventLoop::exec(ProcessEventsFlags flags){
Q_D(QEventLoop);
//we need to protect from race condition with QThread::exitQMutexLocker 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;
}
d->inExec = true;
d->exit = false;
++d->threadData->loopLevel;
d->threadData->eventLoops.push(this);
locker.unlock();
// remove posted quit events when entering a new event loopQCoreApplication *app = QCoreApplication::instance();
if(app && app->thread() == thread())
QCoreApplication::removePostedEvents(app, QEvent::Quit);
#ifdefined(QT_NO_EXCEPTIONS)while(!d->exit)
processEvents(flags | WaitForMoreEvents | EventLoopExec);
// copied abovelocker.relock();
QEventLoop *eventLoop = d->threadData->eventLoops.pop();
Q_ASSERT_X(eventLoop == this, "QEventLoop::exec()", "internal error");
Q_UNUSED(eventLoop); // --release warningd->inExec = false;
--d->threadData->loopLevel;
returnd->returnCode;
}
QEventLoop::exec вызывает QEventLoop::processEvents здесь же в qeventloop.cpp:
boolQEventLoop::processEvents(ProcessEventsFlags flags){
Q_D(QEventLoop);
if(!d->threadData->eventDispatcher)
returnfalse;
if(flags & DeferredDeletion)
QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
returnd->threadData->eventDispatcher->processEvents(flags);
}
который в свою очередь вызывает уже виртуальную фукцию d->threadData->eventDispatcher->processEvents(flags) на код которой в Qt Creator перейти не удается.
Не удается перейти потому , что это плата за кроссплатформенность. То есть реализаций eventDispatcher несколько под каждую операционную систему своя.На самом деле скорее всего это не так и надо бы пересобрать исходники Qt заново.
Кто такой d-> ?
d-> это QObjectData. Поскольку QEventLoop наследуется от QObject:
(class Q_CORE_EXPORT QEventLoop : public QObject)
у него есть QObjectPrivate и QObjectData.
Так вот в QObjectPrivate есть указатель на данные потока :
QThreadData *threadData; // id of the thread that owns the object
Вот это и есть d !
Вспоминаем как объявляли QEventLoop :
QEventLoop eventLoop; // то есть без указания на родителя
потом в eventLoop.exec():
Q_D(QEventLoop); // вот тут и появляется d . Это (в qglobal.h) :
#define Q_D(Class) Class##Private * const d = d_func(), то есть
Q_D(QEventLoop) ===== Class QEventLoopPrivate * const d = d_func();
d_func() в свою очередь это inline подстановка (там же в qglobal.h ):
inlineconstClass##Private* d_func()const{ returnreinterpret_cast(qGetPtrHelper(d_ptr)); }
templatestaticinlinetypenameWrapper::pointer qGetPtrHelper(constWrapper &p){ returnp.data(); }
В итоге d это получается:
QEventLoopPrivate * constd = reinterpret_cast(d_ptr.data());