Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
3 Прикладное программирование на языке c++ с использованием среды Qt Creator 5.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
5.72 Mб
Скачать

Обработка событий с использованием сигналов и слотов

В библиотеке Qt реализован препроцессор MOC (Meta Object Compiler, метаобъектный компилятор) реализующих технологию сигналов и слотов. Этот механизм взаимодействия объектов можно сравнить с теле- радиовещанием. Объект-источник испускает сигнал. Этот сигнал "распространяется" в MOC среде и принимается другими объектами если их приёмники настроены на приём данного сигнала (установлена связь сигнал слот). Такая связь устанавливается с помощью функции connect. Подробнее в [Шлее 5.3, с. 55-71, Секунов с. 18-22, Иванова с. 37-44].

В классах библиотеки Qt реализовано большое количество сигналов и слотов (см. ниже и справку). Кроме того, в собственных классах можно реализовать собственные сигналы и слоты.

Функция connect

Эта функция необходима для установления взаимосвязи между сигналом и слотом.

connect(<источник>, SIGNAL( <сигналИсточника>() ),

<приёмник>, SLOT( <слотПриёмника>() ) );

В данном случае источник и приёмник - указатели на объект-источник и объект-приёмник. Если connect создаётся внутри класса, то часто в качестве приёмника выступает указатель на этот класс (this). Сигналы и слоты могут иметь аргументы. При этом передаются они следующим образом: первый аргумент сигнала передаётся в первый аргумент слота (см. рис.). Примеры возможных конфигураций

connect(<источник>,

SIGNAL(<сигналИсточника>(int, QString) ),

<приёмник>,

SLOT(<слотПриёмника>(int, QString) ) );

или

connect(<источник>,

SIGNAL(<сигналИсточника>(int, QString) ),

<приёмник>,

SLOT(<слотПриёмника>(int) ) );

Рисунок – возможные конфигурации аргументов сигналов и слотов

Число аргументов у слота может быть меньше, чем у сигнала, но парные аргументы всегда должны иметь одинаковый тип. Рассмотрим пример. Если добавить в файл main проекта код

// создание объектов

QPushButton *pb;

pb = new QPushButton("кнопка");

QLineEdit *le;

le = new QLineEdit;

// установление связи

QObject::connect(le, SIGNAL(textChanged(QString)), pb, SLOT(setWindowTitle(QString)));

// отображение на экране

pb->show();

le->show();

то после запуска дополнительно к главному окну появятся ещё два окна (см. рис. ниже а). Редактирование текста в QLineEdit приводит к замене заголовка окна, содержащего кнопку, на этот текст.

а) б)

Рисунок – к работе функции connect()

В случае необходимости установленная связь может быть разорвана с помощью функции disconnect. Интерфейсы функций disconnect и connect идентичны [Шлее 5.3, с. 66].

Создание собственных слотов и сигналов

Создание слота полностью повторяет создание функции внутри класса. Объявить его необходимо в одном из специальных разделов (public slots или private slots). Возвращаемое значение любого слота void. Помимо использования слотов, как аргументов функции connect, они могут быть использованы в коде программы, как простые функции.

Рассмотрим пример иллюстрирующий работу функции connect. Создадим новый проект (см. пример). Разместим на форме объекты классов QPushButton, QCheckBox, QLineEdit и QPlaneTextEdit. Устанавливаем значение сhecked объекта сheckBox как истину (галочка). В конструкторе добавляем строчку

connect(ui->checkBox, SIGNAL(clicked(bool)), ui->plainTextEdit, SLOT(setVisible(bool)) );

Теперь по клику мыши по сheckBox с формы будет исчезать (появляться) объект planeTextEdit. Теперь рассмотрим реализацию слота в объекте mainWindow. Добавляет в область объявления код

private slots:

void addText();

Это объявление нашего слота. Его реализация выглядит как

void MainWindow::addText()

{

if(ui->lineEdit->text().isEmpty() == 0)

{

ui->plainTextEdit->appendPlainText( ui->lineEdit->text() );

ui->lineEdit->clear();

}

}

В конструкторе добавим connect,

connect(ui->pushButton, SIGNAL(clicked(bool)), this, SLOT(addText()) );

который соединяет сигнал нажатия кнопки pushButton и наш слот addText. С исходным кодом данной программы можно ознакомится в примере signalSlot.

Процесс создания сигнала гораздо проще. Для этого его достаточно объявить в разделе signals как и слот, и добавить в коде программы его излучение с помощью ключевого слова emit, см. [Шлее 5.3, с. 58-60]. Отметим, что создание сигналов относительно редкое явление, в отличие от создания слотов, что является одним из основных этапов разработки.