Чтение онлайн

на главную

Жанры

Основы программирования в Linux
Шрифт:
Примечание

Имейте в виду, что сигналы Qt отличаются от сигналов UNIX, обсуждавшихся в главе 11.

Вот как устроено программирование, управляемое событиями: графический интерфейс пользователя состоит из меню, панелей инструментов, кнопок, полей ввода и множества других элементов GUI, называемых виджетами. Когда пользователь взаимодействует с виджетом, например, активизирует пункт меню или вводит какой-то текст в поле ввода, виджет порождает именованный сигнал, такой как

clicked
,
text_changed
или
key_pressed
.
Как правило, вам захочется сделать что-то в ответ на действие пользователя, например, сохранить документ или выйти из приложения, и вы выполняете это, связав сигнал с функцией обратного вызова или слотом на языке Qt.

Применение сигналов и слотов довольно специфично — Qt определяет два новых соответствующим образом описанных псевдоключевых слова,

signals
и
slots
для обозначения в вашем программном коде классов сигналов и слотов. Это замечательно с точки зрения читаемости и сопровождения программного кода, но вы вынуждены пропускать свой код через отдельный этап препроцессорной обработки для поиска и замены этих псевдоключевых слов дополнительным кодом на языке С++.

Примечание

Таким образом, программный код с использованием Qt — не настоящий программный код на С++. Порой это становится проблемой для некоторых разработчиков. См. документацию Qt на Web-сайте http://doc.trolltech.com/, чтобы понять причину применения этих новых псевдоключевых слов в С++. Более того, применение сигналов и слотов не так уж отличается от Microsoft Foundation Classes (MFC, библиотека базовых классов Microsoft) в ОС Windows, в которой также используется модифицированное определение языка С++.

На способы применения сигналов и слотов в Qt есть несколько ограничений, но они не слишком существенные:

 сигналы и слоты должны быть функциями-методами класса-потомка

QObject
;

 при использовании множественного наследования

QObject
должен быть первым в списке класса;

 оператор

Q_OBJECT
должен появляться первым в объявлении класса;

 сигналы нельзя применять в шаблонах;

 указатели на функцию не могут использоваться как аргументы в сигналах и слотах;

 сигналы и слоты не могут переопределяться или обновляться до статуса

public
(общедоступный).

Поскольку вы должны писать ваши сигналы и слоты как потомков объекта

QObject
, логично создавать ваш интерфейс, расширяя и настраивая виджет, начиная с
QWidget
, базового виджета Qt, потомка виджета
QObject
. В комплекте Qt вы почти всегда будете создавать интерфейсы, расширяя такие виджеты, как
QMainWindow
.

Типичное определение класса в файле MyWindow.h для вашего GUI будет напоминать приведенное далее:

class MyWindow : public QMainWindow {

 Q_OBJECT

public:

 MyWindow;

 virtual ~MyWindow;

signals:

 void aSignal;

private slots:

 void doSomething;

}

Ваш класс — наследник объекта

QMainWindow
, который определяет функциональные возможности главного окна в приложении. Аналогичным образом при создании диалогового окна вы определите подкласс
QDialog
. Первым указан оператор
Q_OBJECT
, действующий как метка для препроцессора, за которым следуют обычные объявления конструктора и деструктора. Далее даны определения сигнала и слота.

У вас есть один сигнал и один слот, оба без параметров. Для порождения сигнала

aSignal
вам нужно всего лишь в любом месте программы вызвать функцию
emit
:

emit aSignal;

Это означает, что все остальное обрабатывается Qt. Вам даже не потребуется реализация

aSignal
.

Для применения слотов их нужно связать с сигналом. Делается это соответствующим образом с помощью названного статического метода

connect
класса
QObject
:

bool QObject::connect(const QObject * sender, const char* signal,

 const QObject * receiver, const char * member);

Просто передайте объект, владеющий сигналом (отправитель), функцию сигнала, объект, владеющий слотом (приемником), и в завершение укажите имя слота.

В примере MyWindow, если бы вы захотели связать сигнал

clicked
виджета
QPushButton
с вашим слотом
doSomething
, вы бы написали:

connect(button, SIGNAL(clicked), this, SLOT(doSomething));

Учтите, что необходимо применять макросы

SIGNAL
и
SLOT
для выделения функций сигналов и слотов. Как и в комплекте GTK+, вы можете связать ряд слотов с заданным сигналом и также связать слот с любым количеством сигналов с помощью множественных вызовов функции connect. Если она завершается аварийно, то возвращает
FALSE
.

Остается реализовать ваш слот в виде обычной функции-метода:

void MyWindow::doSomething {

 // Код слота

}

Выполните упражнение 17.2.

Упражнение 17.2. Сигналы и слоты

Теперь, зная основы использования сигналов и слотов, применим их в примере. Усовершенствуйте

QMainWindow
, вставьте в него кнопку и свяжите сигнал кнопки
clicked
со слотом.

1. Введите следующее объявление класса и назовите файл ButtonWindow.h:

#include <qmainwindow.h>

class ButtonWindow : public QMainWindow {

 Q_OBJECT

public:

 ButtonWindow(QWidget *parent = 0, const char *name = 0);

 virtual ~ButtonWindow;

private slots:

 void Clicked;

};

2. Далее следует реализация класса в файле ButtonWindow.cpp:

#include "ButtonWindow.moc"

#include <qpushbutton.h>

Поделиться:
Популярные книги

Варлорд

Астахов Евгений Евгеньевич
3. Сопряжение
Фантастика:
боевая фантастика
постапокалипсис
рпг
5.00
рейтинг книги
Варлорд

Путь Шедара

Кораблев Родион
4. Другая сторона
Фантастика:
боевая фантастика
6.83
рейтинг книги
Путь Шедара

Идущий в тени 5

Амврелий Марк
5. Идущий в тени
Фантастика:
фэнтези
рпг
5.50
рейтинг книги
Идущий в тени 5

Кровь Василиска

Тайниковский
1. Кровь Василиска
Фантастика:
фэнтези
попаданцы
аниме
4.25
рейтинг книги
Кровь Василиска

Вернуть невесту. Ловушка для попаданки

Ардова Алиса
1. Вернуть невесту
Любовные романы:
любовно-фантастические романы
8.49
рейтинг книги
Вернуть невесту. Ловушка для попаданки

Не грози Дубровскому!

Панарин Антон
1. РОС: Не грози Дубровскому!
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Не грози Дубровскому!

Мастер Разума III

Кронос Александр
3. Мастер Разума
Фантастика:
героическая фантастика
попаданцы
аниме
5.25
рейтинг книги
Мастер Разума III

Мимик нового Мира 8

Северный Лис
7. Мимик!
Фантастика:
юмористическая фантастика
постапокалипсис
рпг
5.00
рейтинг книги
Мимик нового Мира 8

На границе империй. Том 9. Часть 5

INDIGO
18. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 9. Часть 5

Идеальный мир для Лекаря 3

Сапфир Олег
3. Лекарь
Фантастика:
фэнтези
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 3

Дядя самых честных правил 7

Горбов Александр Михайлович
7. Дядя самых честных правил
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Дядя самых честных правил 7

С Д. Том 16

Клеванский Кирилл Сергеевич
16. Сердце дракона
Фантастика:
боевая фантастика
6.94
рейтинг книги
С Д. Том 16

Авиатор: назад в СССР 14

Дорин Михаил
14. Покоряя небо
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Авиатор: назад в СССР 14

Сирота

Ланцов Михаил Алексеевич
1. Помещик
Фантастика:
альтернативная история
5.71
рейтинг книги
Сирота