×
Namespaces

Variants
Actions

Механизм сигналов и слотов в Qt

From Nokia Developer Wiki
Jump to: navigation, search
Article Metadata

Совместимость
Платформа(ы):
Symbian

Статья
Автор: Den123 (03 Jan 2009)
Последнее редактирование: hamishwillee (08 May 2013)

Данный материал расширяет и дополняет статью на английском языке, которую можно найти здесь.


Contents

Введение

Сигналы и слоты - это фундаментальный механизм Qt, позволяющий связывать объекты друг с другом. Cвязанным объектам нет необходимости что-либо "знать" друг о друге. Сигналы и слоты гораздо удобнее механизма функций обратного вызова (callbacks) и четко вписываются в концепцию ООП.

Для использования этого механизма объявление класса должно содержать специальный макрос Q_OBJECT на следующей строке после ключевого слова class:

class MyClass {
Q_OBJECT
 
public:
...
 
};

После макроса Q_OBJECT не нужно ставить точку с запятой. Перед выполнением компиляции, Meta Object Compiler (MOC) анализирует такие классы и автоматически внедряет в них всю необходимую информацию (используются отдельные файлы, разработчик может их игнорировать).

Наследники QObject могут иметь любое количество сигналов и слотов.

Сигналы

Сигнал может быть определен следующим образом:

class MyClass: public QObject {
Q_OBJECT
 
public:
...
 
signals:
void mySignal();
 
};


Для того чтобы инициировать сигнал (выслать сигнал) нужно ипользовать ключевое слово emit.

void MyClass ::sendMySignal()
{
emit mySignal();
}

Сигналы могут использовать параметры для передачи дополнительной информации.


Слоты

Слоты практически идентичны обычным членам-методам C++, при их объявлении можно использовать стандартные спецификаторы доступа public, protected или private. Слоты можно вызывать напрямую, как обычные члены-функции класса C++. Главная особенность слотов - это возможность связывания с сигналами, в этом случае слоты будут вызваться автоматически при каждом возникновении соответствующих сигналов. В слотах нельзя использовать параметры по умолчанию.

Слот может быть определен следующим образом:

class MyClass: public QObject {
Q_OBJECT
 
public slots:
void mySlot()
{
...
}
 
};

В теле слота можно узнать, какой объект выслал сигнал.

Соединение сигналов и слотов

Для соединения сигналов и слотов можно использовать статический метод connect, определенный в классе QObject. В общем виде соединение выглядит следующим образом:

connect(sender, SIGNAL(signal), receiver, SLOT(slot));

sender и receiver - это указатели на QObject.
signal и slot - сигнатуры сигнала и слота.

Пример соединения:

QObject::connect(spinBox, SIGNAL(valueChanged(int)),slider, SLOT(setValue(int)));

В приведенном выше примере, сигнал, возникающий при каждом изменении объекта spinbox, связывается с соответствующим слотом объекта slider. Вызов слота slider.setValue(int) происходит автоматически при каждом возникновении сигнала spinBox.valueChanged(int).

Существует множество различных вариантов соединения сигналов и слотов.

  • Один сигнал может быть соединен со многими слотами:
connect(slider, SIGNAL(valueChanged(int)),spinBox, SLOT(setValue(int)));
connect(slider, SIGNAL(valueChanged(int)),this, SLOT(updateStatusBarIndicator(int)));

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

  • Множество сигналов могут быть соединены с единственным слотом:
connect(sender0, SIGNAL(overflow()),receiver1, SLOT(handleMathError()));
connect(sender1, SIGNAL(divisionByZero()),receiver1, SLOT(handleMathError()));
  • Сигналы могут быть соединены между собой:
connect(sender1, SIGNAL(function1()),receiver, SIGNAL(function2()));

При возникновении первого сигнала, автоматически генерируются все сязанные сигналы. Не считая этого, соединение сигнал-сигнал неотличимо от соединения сигнал-слот.

Разъединение сигналов и слотов

  • Метод disconnect можно использовать для того, чтобы удалить соединение между сигналом и слотом.
disconnect(sender0, SIGNAL(overflow()),receiver1, SLOT(handleMathError()));

На практике прямой вызов disconnect используется редко, так как Qt автоматически удаляет все соединения при удалении объектов.

This page was last modified on 8 May 2013, at 03:00.
331 page views in the last 30 days.
×