На этом шаге продолжим рассматривать пример создания диалогового окна поиска.
Теперь рассмотрим файл finddialog.срр, в котором находится реализация класса FindDialog.
#include <QLabel> #include <QDialog> //включаем заголовочные файлы, которые содержат #include <QLineEdit> //определения классов графического интерфейса Qt. #include <QCheckBox> //Qt состоит из нескольких модулей, каждый из которых #include <QPushButton> //находится в своей собственной библиотеке #include <QHBoxLayout> #include <QVBoxLayout> #include "finddialog.h" //Конструктору базового класса передается указатель на //родительский виджет (параметр parent) FindDialog::FindDialog(QWidget *parent) : QDialog(parent) { //Создаем дочерние виджеты. //Функция tr() переводит строковые литералы на другие языки. //Она объявляется в классе QObject и в каждом подклассе, //содержащем макрос Q_OBJECT. //Любое строковое значение, которое пользователь будет видеть на экране, //полезно преобразовывать функцией tr(), даже если вы не планируете //в настоящий момент переводить ваше приложение на какой-нибудь другой язык //Мы используем знак амперсанда (&) для задания клавиш быстрого доступа. //Амперсанды могут также применяться для управления фокусом: //создаем текстовую метку с клавишей быстрого доступа (Alt+Н) label = new QLabel(tr("&Найти:")); lineEdit = new QLineEdit; //устанавливаем строку редактирования в качестве "партнера" //этой текстовой метки. Партнером (buddy) называется виджет, //на который передается фокус при нажатии клавиши быстрого доступа //текстовой метки. Поэтому при нажатии пользователем сочетания клавиш Alt+Н //(клавиша быстрого доступа текстовой метки) фокус переходит на //строку редактирования (которая является партнером текстовой метки) label->setBuddy(lineEdit); caseCheckBox = new QCheckBox(tr("&Учитывать регистр")); backwardCheckBox = new QCheckBox(tr("Искать &вверх")); //Cоздается кнопка Найти далее, которая может быть активирована //нажатием пользователем сочетания клавиш Alt+д на платформах, //поддерживающих клавиши быстрого доступа findButton = new QPushButton(tr("Найти &далее")); //мы делаем кнопку Найти далее используемой по умолчанию, //вызывая функцию setDefault(true). //Кнопка, для которой задан режим использования по умолчанию, //будет срабатывать при нажатии пользователем клавиши Enter findButton->setDefault(true); //устанавливаем кнопку Найти далее в неактивный режим. //В неактивном режиме виджет обычно имеет серый цвет и не реагирует //на действия пользователя findButton->setEnabled(false); closeButton = new QPushButton(tr("&Закрыть")); //Закрытый слот enableFindButton(const QString &) вызывается //при всяком изменении значения в строке редактирования connect(lineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(enableFindButton(const QString &))); //Закрытый слот findClicked() вызывается при нажатии //пользователем кнопки Найти далее connect(findButton, SIGNAL(clicked()), this, SLOT(findClicked())); //Само диалоговое окно закрывается при нажатии пользователем //кнопки Закрыть. Слот close () наследуется от класса QWidget, //и по умолчанию он делает виджет невидимым (но не удаляет его) connect(closeButton, SIGNAL(clicked()), this, SLOT(close())); //Для размещения виджетов в окне мы используем менеджеры компоновки. //Менеджеры компоновки могут содержать как виджеты, //так и другие менеджеры компоновки. Используя различные вложенные //комбинации менеджеров компоновки QHBoxLayout, QVBoxLayout //и QGridLayout, можно построить очень сложные диалоговые окна. Для диалогового //окна поиска мы используем два менеджера горизонтальной компоновки QHBoxLayout //и два менеджера вертикальной компоновки QVBoxLayout (рис. 1). //Первые три менеджера компоновки являются внутренними QHBoxLayout *topLeftLayout = new QHBoxLayout; topLeftLayout->addWidget(label); topLeftLayout->addWidget(lineEdit); QVBoxLayout *leftLayout = new QVBoxLayout; leftLayout->addLayout(topLeftLayout); leftLayout->addWidget(caseCheckBox); leftLayout->addWidget(backwardCheckBox); QVBoxLayout *rightLayout = new QVBoxLayout; rightLayout->addWidget(findButton); rightLayout->addWidget(closeButton); //Показанная в нижнем правом углу на рис. 1 маленькая "пружинка" //является пустым промежутком ("распоркой"). //Она применяется для образования ниже кнопок Найти далее и Закрыть //пустого пространства, обеспечивающего перемещение кнопок //в верхнюю часть своего менеджера компоновки. rightLayout->addStretch(); //Внешний менеджер компоновки является главным; он ответствен //за всю область, занимаемую диалоговым окном QHBoxLayout *mainLayout = new QHBoxLayout; //При добавлении внутренних менеджеров компоновки к родительскому менеджеру //компоновки для них автоматически устанавливается родительская связь mainLayout->addLayout(leftLayout); mainLayout->addLayout(rightLayout); //Когда главный менеджер компоновки устанавливается для диалога, //он становится дочерним элементом диалога и все виджеты в //менеджерах компоновки становятся дочерними элементами диалога. //Иерархия полученных родословных связей представлена на рис. 2. setLayout(mainLayout); //Задаем название диалогового окна и устанавливаем фиксированной его высоту, //поскольку в диалоговом окне нет виджетов, которым может понадобиться //дополнительное пространство по вертикали. Функция //QWidget::sizeHint() возвращает "идеальный" размер виджета setWindowTitle(tr("Найти")); setFixedHeight(sizeHint().height()); }
Рис.1. Менеджеры компоновки диалогового окна поиска данных
Рис.2. Родословная объектов диалогового окна поиска данных
На этом завершается рассмотрение конструктора FindDialog. Поскольку нами использован оператор new при создании виджетов и менеджеров компоновки, нам, по-видимому, придется написать деструктор, где будут предусмотрены операторы delete для удаления каждого созданного нами виджета и менеджера компоновки. Но поступать так не обязательно, поскольку Qt автоматически удаляет дочерние объекты при разрушении родительского объекта, а все дочерние виджеты и менеджеры компоновки являются потомками FindDialog.
На следующем шаге продолжим рассматривать пример создания диалогового окна поиска.