вступление

Картинка для общего примерного представления :

фотка 1

Теперь о главном - о практических нюансах .

Сигнал выпускается в коде командой emit. Но на самом деле это больше похоже не на сигнал , а на вызов обычной функции , так как при вызове emit пока все соединенные слоты не будут выполнены (кстати в непредсказуемом порядке) , то выполнение кода после emit не происходит. То есть очередей тут никаких нет.

Правда есть исключение - это queued connections.

Чтобы дождаться окончания выполнение асинхронных команд и НЕ подвешивать обработчик событий часто используют такую конcтрукцию:

QEventLoop loop;
QNetworkReply *reply = qnam.post(request , ba);
connect(reply, SIGNAL(finished()),&loop, SLOT(quit()));
loop.exec();

Это связано с тем , что QNetworkReply создает и использует свой поток, синхронизацию с которым как раз удобно релизовывать через сигналы/слоты.

Это пример выполнения http запроса к серверу. Пока запрос не отработает , то есть не придет сигнал finished от QNetworkReply , код далее (чем loop.exec();) выполняться не будет.

Минус технологии сигнал/слот в том , что если что-то поменять , то надо очищать проект и делать заново qmake и полную пересборку проекта.

Неоспоримым преимуществом технологии является возможность где угодно делать вызовы сигналов emit и не беспокоится связан с ними какой-нибудь слот (слоты) или нет... Это реально просто удобно.

Вообще говоря по нашему скромному опыту сигнал/слот удобен для релизации обратной связи процессов.

Для "прямого" управления существуют абстрактные классы и по-видимому этого вполне достаточно.

Именно так и поступали разработчики Qt при создании своей библиотеки, пихали везде emit-ты и вы могли их соединять со своими слотами в своих объектах , а могли и не соединять (и даже вообще могли не подозревать о их существовании).

Слоты - возвращаемые значения

Передавать как параметры слотов можно похоже все, что угодно: QVariantMap например, структуры.

Передаются параметры не по ссылке или указателю , в полностью с выделением памяти под их копию.

Можно возвращать тип int , перечисления enum и т.д.

То есть делаем примерно так int res= emit sig_connecTest();

Еще замечено , что на перепутанные большие / маленькие буквы в названиях слотов в конструкции connect(..) компилятор не ругается.

Интересное наблюдение

На самом деле вы можете связывать сигнал / слот для объектов , которые передаются по как указатель на QObject, но самом деле это какой-то класс унаследованный от QObject, но мы даже можем не знать какой именно класс.

Например есть классы
class A: public QObject
A::A(QObject * obj){}

class B: public QObject

B* b=new B()
A* a = new A(b)

В конструкторе А передадим указатель QObject* , на самом деле это указатель на класс B :

Теперь в классе A мы ничено не знаем о классе B, но тем не менее можем сделать connect на слот класса B:

connect(this ,SIGNAL(...), obj ,SLOT(...))

И это будет работать.