Вот скорее всего он в другом треде эмитируется. Но не QThread.
Но ведь как я понял, сигнал по умолчанию поставится в очередь? И другой тред на время получения сигнала заблокируется, верно? Ну так вот, ничего не блокируется. Сигнал эмитируется, но слот не вызывается.
If no event loop is running, events won't be delivered to the object. For example, if you create a QTimer object in a thread but never call exec(), the QTimer will never emit its timeout() signal. Calling deleteLater() won't work either. (These restrictions apply to the main thread as well.)
Все сигналы коннектятся по умолчанию, т.е. АutoConnect. Но, думаю, что остальные сигналы вызываются directly, так как они в одном треде. А этот, возможно в другом.
Тут надо заметить, что конкретный тип подключения по-умолчанию выбирается исходя из того к каким потокам принадлежат связываемые объекты (man QObject::moveToThread), а не из того в каком потоке вызывается сигнал.
Если указать QueuedConnection - то нифига не происходит. Слот не вызывается.
Если же указать DirectConnection - то приложение падает с криком, что доступ к гую может быть только из гуевого треда. (Видимо в этом случае слот вызвался. :) )
Connect может вернуть true на любую хрень. Можно засунуть SLOT(blabla(int)) - и ошибиться с сигнатурой - SLOT всё преобразует в строку и плевать хотел что в ней. Например у вас есть слот blabla(int), а вы написали blabla(unsigned) - connect-у на это пофиг, он не проверяет, но ничего не законнектится.
Если кому-то интересно. Дело было в кастомном типе данных. Кастомный тип нужно предварительно зарегистрировать в системе типов Qt. Без этого сигнал не будет работать.