Далее мы обсудим механизм программирования, управляемого событиями, и вы вставите в приложение виджет PushButton
.
Сигналы и слоты
Как вы видели в
Имейте в виду, что сигналы Qt отличаются от сигналов UNIX, обсуждавшихся в
Вот как устроено программирование, управляемое событиями: графический интерфейс пользователя состоит из меню, панелей инструментов, кнопок, полей ввода и множества других элементов 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
: