На этом шаге рассмотрим пример, демонстрирующий механизм сигналов и слотов.
Создадим приложение, в первом окне которого находится кнопка нажатия, а во втором — виджет надписи. При щелчке на кнопке Увеличить происходит увеличение отображаемого значения на 1. Как только значение будет равно 5, произойдет выход из приложения.
Рис.1. Демонстрация механизма сигналов и слотов
Это приложение можно взять здесь.
Приведем листинг файла main.cpp:
#include <QApplication> #include <QLabel> #include <QPushButton> #include "counter.h" int main(int argc, char* argv[]) { QApplication app(argc, argv); app.setApplicationDisplayName("Счетчик"); QLabel *lbl=new QLabel("0"); QPushButton *cmd=new QPushButton("Увеличить"); Counter counter; lbl->show(); cmd->show(); QObject::connect(cmd,SIGNAL(clicked()),&counter,SLOT(slotInc())); QObject::connect(&counter,SIGNAL(counterChanged(int)),lbl,SLOT(setNum(int))); QObject::connect(&counter,SIGNAL(goodbye()),&app,SLOT(quit())); return app.exec(); }
В основной программе приложения main.cpp создается объект типа QApplication и определяется свойство applicationDisplayName(), значением Счетчик. Оно будет отображаться в заголовке окна приложения. Затем создается объект надписи lbl, нажимающаяся кнопка cmd и объект счетчика counter (описание которого приведено в листингах ниже).
Далее сигнал clicked() соединяется со слотом slotInc(). При каждом нажатии на кнопку вызывается метод slotInc(), увеличивая значение счетчика на 1. Он должен быть в состоянии сообщать о подобных изменениях, чтобы элемент надписи отображал всегда только актуальное значение.
Для этого сигнал counterChanged(int), передающий в параметре актуальное значение счетчика, соединяется со слотом setNum(int), способным принимать это значение.
Сигнал goodbye(), символизирующий окончание работы счетчика, соединяется со слотом объекта приложения quit(), который осуществляет завершение работы приложения, после нажатия кнопки Увеличить в пятый раз.
Наше приложение состоит из двух окон, и после закрытия последнего окна его работа автоматически завершится.
Приведем листинг файла Counter.h:
#ifndef COUNTER_H #define COUNTER_H #include <QObject> class Counter: public QObject { Q_OBJECT private: int m_nValue; public: Counter(); public slots: void slotInc(); signals: void goodbye(); void counterChanged(int); }; #endif // COUNTER_H
Как видно из листинга, в определении класса счетчика содержатся два сигнала: goodbye(), сообщающий о конце работы счетчика, и counterChanged(int), передающий актуальное значение счетчика, а также слот slotInc(), увеличивающий значение счетчика на единицу.
Приведем листинг файла сounter.cpp:
#include<Counter.h> Counter::Counter():QObject(),m_nValue(0) { } void Counter::slotInc() { emit counterChanged(++m_nValue); if (m_nValue==5) { emit goodbye(); } }
Метод слота slotInc() отправляет два сигнала: counterChanged() и goodbye(). Сигнал goodbye() отправляется при значении атрибута m_nValue, равном 5.
Для корректной работы приложения, необходимо в файл проекта добавить следующие строки:
QT += widgets QT += gui
На следующем шаге рассмотрим метод disconnect() для разъединения объектов.