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

на главную - закладки

Жанры

Основы программирования в 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>

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

Звездная Кровь. Экзарх II

Рокотов Алексей
2. Экзарх
Старинная литература:
прочая старинная литература
5.00
рейтинг книги
Звездная Кровь. Экзарх II

Второгодка. Книга 2. Око за око

Ромов Дмитрий
2. Второгодка
Фантастика:
героическая фантастика
альтернативная история
фэнтези
5.00
рейтинг книги
Второгодка. Книга 2. Око за око

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

INDIGO
Вселенная EVE Online
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 10. Часть 13

Третий

INDIGO
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
Третий

Сердце Дракона. нейросеть в мире боевых искусств (главы 1-650)

Клеванский Кирилл Сергеевич
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
7.51
рейтинг книги
Сердце Дракона. нейросеть в мире боевых искусств (главы 1-650)

Боярышня Дуняша 2

Меллер Юлия Викторовна
2. Боярышня
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Боярышня Дуняша 2

ЖЛ 8

Шелег Дмитрий Витальевич
8. Живой лед
Фантастика:
аниме
5.60
рейтинг книги
ЖЛ 8

Искатель 2

Шиленко Сергей
2. Валинор
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Искатель 2

Охотник

Щепетнов Евгений Владимирович
Фантастика:
фэнтези
боевая фантастика
5.40
рейтинг книги
Охотник

Убивать чтобы жить 4

Бор Жорж
4. УЧЖ
Фантастика:
боевая фантастика
рпг
5.00
рейтинг книги
Убивать чтобы жить 4

Ваше Сиятельство 3

Моури Эрли
3. Ваше Сиятельство
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Ваше Сиятельство 3

Ты - наша

Зайцева Мария
1. Наша
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
Ты - наша

Отмороженный 13.0

Гарцевич Евгений Александрович
13. Отмороженный
Фантастика:
боевая фантастика
попаданцы
рпг
фантастика: прочее
фэнтези
5.00
рейтинг книги
Отмороженный 13.0

Я не князь. Книга XIII

Дрейк Сириус
13. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я не князь. Книга XIII