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