Программирование на C++ с использованием библиотеки Qt4

         

Assistant


) находим, что в классе QAbstractSlider, потомком которого является QScrollBar, определён сигнал void QAbstractSlider::valueChanged ( int value ) оповещающий об изменении положения ползунка полосы прокрутки. Далее, в описании класса QLabel находим, что изменение текста надписи производится с помощью функции setText(строка) или setNum(число). Тогда вызов метода connect должен выглядеть следующим образом: QObject::connect( scrollBar, // Источник события. SIGNAL(valueChanged(int)), // Сигнал. label, // Объект-приёмник сигнала. SLOT( setNum(int) ) ); // Функция-обработчик. Заметим, что параметрами сигнала и слота являются типы, а не переменные.

Количество параметров слота всегда не больше количества параметров сигнала. Соответствие между ними, как обычно, позиционное: при выполнении программы значением i-го параметра слота становится значение i-го параметра сигнала.

В объявлении класса методы-слоты необходимо указывать в разделе publicslots или private slots. Обычно в программе используются стандартные сигналы, но если требуется определить собственные, то их надо объявить в разделе signals. Например: class MainWondow : public QMainWindow { Q_OBJECT ............. signals: void mySignal(); private slots: void onMySignal(); .............

Сигнал может быть "соединён" с другим сигналом, например: connect( myButton, SIGNAL( clicked() ), this, SIGNAL( buttonClicked() ) );

Один и тот же сигнал можно связать с несколькими слотами и/или другими сигналами. С одним и тем же слотом можно связать несколько сигналов. Можно указать несколько одинаковых "соединений": тогда одно событие вызовет генерацию нескольких сигналов.

Чтобы разорвать связь между сигналом и слотом, используется метод disconnect: bool QObject::disconnect ( const QObject *sender, const char *signal, const QObject *receiver, const char *method ) [static]

В листинге 5 приведён текст небольшой программы, иллюстрирующей принцип обработки нажатия на кнопку (экземпляр класса QPushButton), а на рис. показано, как выглядит окно программы в системе Windows.



файл examples-qt/01/01.cpp)


1 // Сигналы и слоты: кнопка в окне 2 3 #include <QApplication>
4 #include <QPushButton>
5 6 int main(int argc, char *argv[]) { 7 8 QApplication app(argc, argv);
9 10 QPushButton *button = new QPushButton( 11 QString::fromLocal8Bit("&Выход") );
// Кнопка. 12 button->
setFont(QFont("Times", 16, QFont::Bold));
13 QObject::connect( 14 button, // Источник сигнала. 15 SIGNAL(clicked()), // Сигнал о нажатии кнопки. 16 &app, // Приёмник сигнала. 17 SLOT( quit() ) );
// Функция-слот (обработчик события). 18 button->
show();
19 20 return app.exec();
21 } Здесь мы разместили в окне обычную кнопку (10-11) с надписью "Выход" и связали её нажатие -- сигнал clicked (15) -- с функцией-обработчиком quit (17), которая завершает приложение app. Заметим, что мы не создаём главное окно для кнопки, это будет сделано автоматически (рис.).

Символ "&" перед буквой "В" в тексте надписи на кнопке (11) позволяет активировать её не только по щелчку левой кнопкой мыши или нажатием клавиши Enter, но также с помощью комбинации клавиш Alt+в (к сожалению, только в режиме ввода кириллицы).



Обработка событий


Для связывания событий, происходящий с объектами, и функций, предназначенных для обработки этих событий, в библиотеке Qt используется интересный механизм



Слотов


. Сигнал -- это сообщение о том, что произошло какое-либо событие, например, нажатие на кнопку или выбор пункта меню. Вся информация о событии сохраняется в полях экземпляра соответствующего класса. У сигнала есть источник (например, кнопка) и приёмник (объект, метод которого будет обрабатывать это событие). Слот -- это сама функция-обработчик события. Связь между всеми четырьмя перечисленными элементами задаётся с помощью метода connect (соединить): bool QObject::connect ( const QObject *sender, // Источник события. const char *signal, // Сигнал. const QObject *receiver, // Объект-приёмник сигнала. const char *method, // Функция-обработчик. Qt::ConnectionType type = Qt::AutoConnection ) const Последний параметр определяет режим обработки: Qt::DirectConnection -- событие обрабатывается сразу; Qt::QueuedConnection -- событие ставится в общую очередь и будет обработано только после всех сообщений, уже имеющихся в этой очереди; Qt::AutoConnection -- если источник события находится в том же потоке, что и приёмник, то будет использован режим Qt::DirectConnection, в противном случае -- Qt::QueuedConnection.

Для определения сигнала и слота используются макросы SIGNAL и SLOT. Например, мы хотим, чтобы текстовая метка label (экземпляр класса QLabel) отображала позицию полосы прокрутки scrollBar (экземпляр класса QScrollBar). В документации на библиотеку Qt (открыв doc/html/index.html или программу