Немного издали... Если сигнал подключается к слоту с флагом Qt::AutoConnection (используется по умолчанию) или Qt::DirectConnection, и вызываемый слот принадлежит объекту, находящемуся в том же потоке, что и объект, от которого исходит сигнал, то никакой обработчик очереди событий не вызывается. Производится вызов слота прямо на месте. Если этот слот посредством прямого подключения через сигнал будет вызывать сам себя, то случится бесконечная рекурсия, вплоть до переполнения стека, ну и конечно неизбежного краха приложения.
Для того, чтобы связка сигнал-слот срабатывала через очередь в рамках одного и того же потока необходимо всегда явно указывать флаг Qt::QueuedConnection. Только в этом случае создаётся соответствующий наследник класса события, который и помещается в очередь событий.
Внутренняя реализация QTimer пользуется методами регистрации таймеров операционной системы, на которой выполняется приложение (это позволяет указывать таймеру дополнительные флаги, в случае, если требуется, например, повышенная точность). Соответственно, именно она формирует события о том, что время такого-то таймера в очередной раз истекло. Точно такие же события поступают при движении курсора мыши и нажатии клавиш. Эти нативные события попадают в очередь событий приложения одно за другим.
Все события обрабатываются строго по очереди. Здесь как никогда верно правило: "Кто первый встал, того и тапки". Это означает, что если таймер создан с точностью, допускающей определённую погрешность в интервале, то события таймера будут поступать на обработку с непредсказуемым (в рамках погрешности, разумеется) интервалом и могут попасть в очередь до или после любого другого события.
Если объект таймера существует в отдельном потоке, у которого имеется своя собственная очередь событий, и при этом будет пытаться вызывать слот объекта, находящегося в другом потоке, то событие о вызове слота попадёт в очередь событий целевого потока. В этом случае будет действовать ровно то же самое правило про тапки: если перед поступившим событием уже имеются какие-то события, то будут выполнены сначала они, а событие таймера на вызов слота подождёт своей очереди.
Однако существуют подводные камни, возможность появления которых стоит иметь в виду. Предположим, имеется следующая схема:
Событие А: слот СЛОТ вызывает сам себя через очередь событий;
Событие Б: таймер вызывает СЛОТ с неким интервалом;
Получится следующее:
Вызовы А будут идти друг за другом, как и положено. Поскольку каждое новое событие всегда встаёт вконец очереди, то вызов Б через какое-то время без проблем вклинится в порядок вызовов А. Однако каждый вызов слота СЛОТ всегда порождает новый вызов А. Таким образом, после каждого Б будет порождаться не один новый А, а второй, третий (и т.д.) бесконечные циклы из А.
QObject::destroyed(), может быть заблокирован при помощиQObject::blockSignals(). С таймером получится так, что к нему событие о таймауте от системы придёт, а он свой сигнал не создаст и не отправит. – Jun 20 '16 at 13:35