На этом шаге рассмотрим метод connect() для соединения объектов.
Соединение объектов осуществляется при помощи статического метода connect(), который определен в классе QObject.
В общем виде, вызов метода connect() выглядит следующим образом:
QObject::connect(const QObject* sender, const char* signal, const QObject* receiver, const char* slot, Qt::ConnectionType type = Qt::AutoConnection );
Параметры:
- sender — указатель на объект, отправляющий сигнал;
- signal — это сигнал, с которым осуществляется соединение. Прототип (имя и аргументы) метода сигнала должен быть заключен в специальный макрос SIGNAL(method());
- receiver — указатель на объект, который имеет слот для обработки сигнала;
- slot — слот, который вызывается при получении сигнала. Прототип слота должен быть заключен в специальном макросе SLOT(method());
- type — управляет режимом обработки. Имеется три возможных значения:
- Qt::DirectConnection — сигнал обрабатывается сразу вызовом соответствующего метода слота,
- Qt::QueuedConnection — сигнал преобразуется в событие и ставится в общую очередь для обработки,
- Qt::AutoConnection — это автоматический режим, который действует следующим образом: если отсылающий сигнал объект находится в одном потоке с принимающим его объектом, то устанавливается режим Qt::DirectConnection, в противном случае — режим Qt::QueuedConnection. Этот режим (Qt::AutoConnection) определен в методе connection() по умолчанию. Вам вряд ли придется изменять режимы "вручную", но полезно знать, что такая возможность есть.
Следующий пример демонстрирует то, как может быть осуществлено соединение объектов в программе.
void main() { ... QObject::connect(pSender, SIGNAL(signalMethod()), pReceiver, SLOT(slotMethod()) ); ... }
Если вызов происходит из класса, унаследованного от QObject, тогда QObject:: можно опустить:
MyClass ::MyClass() : QObject() { ... connect(pSender, SIGNAL(signalMethod()), pReceiver, SLOT(slotMethod()) ); ... }
В случае если слот содержится в классе, из которого производится соединение, то можно воспользоваться сокращенной формой метода connect(), опустив третий параметр (pReceiver), указывающий на объект-получатель. Другими словами, если в качестве объекта-получателя должен стоять указатель this, его можно просто не указывать:
MyClass::MyClass() : QObject() { connect(pSender, SIGNAL(signalMethod()), SLOT(slot())); } void MyClass::slot() { qDebug() << "Я слот"; }
Иногда возникают ситуации, когда объект не обрабатывает сигнал, а просто передает его дальше. Для этого необязательно определять слот, который в ответ на получение сигнала (при помощи emit) отсылает свой собственный. Можно просто соединить сигналы друг с другом. Отправляемый сигнал должен содержаться в определении класса:
MyClass::MyClass() : QObject() { connect(pSender, SIGNAL(signalMethod()), SIGNAL(mySignal())); }
Отправку сигналов можно заблокировать на некоторое время, вызвав метод blockSignals() с параметром true. Объект будет "молчать", пока блокировка не будет снята тем же методом blockSignals() с параметром false.
При помощи метода signalsBlocked() можно узнать текущее состояние блокировки сигналов.
Слот, не имеющий параметров, можно соединить с сигналом, имеющим параметры. Это удобно, когда сигналы поставляют больше информации, чем требуется для объекта, получающего сигнал. В этом случае в слоте можно не указывать параметры:
MyClass::MyClass() : QObject() { connect(pSender, SIGNAL(signalMethod(int)), SIGNAL(mySignal())); }
Если вы не уверены, пригодится ли параметр сигнала в будущем, то лучше определить слот с параметром и проигнорировать его внутри слота. Зато потом, когда возникнет необходимость, вам не потребуется менять прототип слота.
На следующем шаге рассмотрим пример, демонстрирующий механизм сигналов и слотов.
Предыдущий шаг
Содержание
Следующий шаг