[Предыдущий: Адресная книга. Урок 1 - Проектирование пользовательского интерфейса] [Содержание] [Следующий: Урок 3]
Адресная книга. Урок 2 - Добавление адресов
Файлы:
Следующим шагом в создании нашего базового приложения адресной книги будет предоставление небольшого взаимодействия с пользователем.
Мы предоставим кнопку, которую пользователь может нажимать для добавления нового контакта. Для упорядоченного хранения этих контактов необходимы также некоторые формы структур данных.
Определение класса AddressBook
Теперь, когда мы имеем установленные метки и поля ввода, добавим кнопки для завершения процесса добавления контакта. Это означает, что наш файл addressbook.h теперь содержит три объявленных объекта QPushButton и три соответствующих открытых слота.
public slots:
void addContact();
void submitContact();
void cancel();
Слот - функция, которая реагирует на особый сигнал. Мы обсудим эту концепцию в дальнейшем, при реализации класса AddressBook. Тем не менее, обзор концепции сигналов и слотов Qt вы можете найти в документе Сигналы и слоты.
Три объекта QPushButton - addButton, submitButton и cancelButton - теперь включены в объявления закрытых переменных, наряду с nameLine и addressText из предыдущего урока.
private:
QPushButton *addButton;
QPushButton *submitButton;
QPushButton *cancelButton;
QLineEdit *nameLine;
QTextEdit *addressText;
Нам нужен такой контейнер для хранения контактов из нашей адресной книги, чтобы мы могли перебирать эти контакты и отображать их на экране. Объект класса QMap, contacts, используется в этих целях поскольку он содержит пару ключ-значение: имя контакта выступает в качестве ключа, а адрес контакта - в качестве значения.
QMap<QString, QString> contacts;
QString oldName;
QString oldAddress;
};
Также мы объявляем два закрытых объекта класса QString - oldName и oldAddress. Эти объекты нужны для хранения имени и адреса последнего отображаемого контакта до тех пор, пока пользователь не щелкнет по кнопке Add. Таким образом, когда пользователь щелкнет по кнопке Cancel, мы можем вернуться к отображению на экране деталей последнего контакта.
Реализация класса AddressBook
Внутри конструктора AddressBook мы устанавливаем nameLine и addressText только для чтения, так что мы можем только отображать, но не редактировать детали имеющихся контактов.
...
nameLine->setReadOnly(true);
...
addressText->setReadOnly(true);
Затем мы создаем экземпляры кнопок: addButton, submitButton и cancelButton.
addButton = new QPushButton(tr("&Add"));
addButton->show();
submitButton = new QPushButton(tr("&Submit"));
submitButton->hide();
cancelButton = new QPushButton(tr("&Cancel"));
cancelButton->hide();
Кнопка addButton отображается на экране после вызова функции show(), в то время как кнопки submitButton и cancelButton скрыты после вызова hide(). Эти две кнопки будут отображены только тогда, когда пользователь щелкнет по кнопке "Add", что будет обработано обсуждаемой ниже функцией addContact().
connect(addButton, SIGNAL(clicked()), this, SLOT(addContact()));
connect(submitButton, SIGNAL(clicked()), this, SLOT(submitContact()));
connect(cancelButton, SIGNAL(clicked()), this, SLOT(cancel()));
Мы соединили сигнал кнопок clicked() с соответствующими им слотами. Рисунок ниже проиллюстрирует это.
Далее, мы аккуратно располагаем наши кнопки в правой части нашего виджета адресной книги, используя QVBoxLayout чтобы разместить их в вертикальный столбец.
QVBoxLayout *buttonLayout1 = new QVBoxLayout;
buttonLayout1->addWidget(addButton, Qt::AlignTop);
buttonLayout1->addWidget(submitButton);
buttonLayout1->addWidget(cancelButton);
buttonLayout1->addStretch();
Функция addStretch() используется не для того, чтобы гарантировать равномерное расположение кнопок, но чтобы разместить их ближе к верхней части виджета. Рисунок ниже показывает разницу между использованием и не использованием addStretch().
Затем мы добавим buttonLayout1 к mainLayout, используя addLayout(). Это предоставит нам вложенную компоновку, так как buttonLayout1 теперь является дочерним по отношению к mainLayout.
QGridLayout *mainLayout = new QGridLayout;
mainLayout->addWidget(nameLabel, 0, 0);
mainLayout->addWidget(nameLine, 0, 1);
mainLayout->addWidget(addressLabel, 1, 0, Qt::AlignTop);
mainLayout->addWidget(addressText, 1, 1);
mainLayout->addLayout(buttonLayout1, 1, 2);
Наши координаты компоновки выглядят теперь так:
В функции addContact() мы сохраняем детали последнего отображаемого на экране контакта в oldName и oldAddress. Затем мы очищаем эти поля ввода и отключаем режим "только для чтения". Устанавливаем фокус ввода на nameLine и отображаем кнопки submitButton и cancelButton.
void AddressBook::addContact()
{
oldName = nameLine->text();
oldAddress = addressText->toPlainText();
nameLine->clear();
addressText->clear();
nameLine->setReadOnly(false);
nameLine->setFocus(Qt::OtherFocusReason);
addressText->setReadOnly(false);
addButton->setEnabled(false);
submitButton->show();
cancelButton->show();
}
Функцию submitContact() можно разделить на три части:
- Мы извлекаем детали контакта из nameLine и addressText и сохраняем их в объектах QString. Также мы проверяем их достоверность чтобы убедиться, что пользователь не щелкнул по кнопке Submit с пустыми полями ввода; в противном случае, на экран будет выведено напоминание пользователю QMessageBox о вводе имени и адреса.
void AddressBook::submitContact()
{
QString name = nameLine->text();
QString address = addressText->toPlainText();
if (name == "" || address == "") {
QMessageBox::information(this, tr("Empty Field"),
tr("Please enter a name and address."));
return;
}
- Затем мы проверяем существует ли контакт. Если нет, то мы добавляем контакт в contacts и выводим на экране QMessageBox, чтобы сообщить пользователю о добавлении контакта.
if (!contacts.contains(name)) {
contacts.insert(name, address);
QMessageBox::information(this, tr("Add Successful"),
tr("\"%1\" has been added to your address book.").arg(name));
} else {
QMessageBox::information(this, tr("Add Unsuccessful"),
tr("Sorry, \"%1\" is already in your address book.").arg(name));
return;
}
Если контакт существует, мы также выведем на экран QMessageBox, чтобы сообщить пользователю об этом и предупреждая его о добавлении дубля существующего контакта. Наш объект contacts основан на парах ключ-значение - имени и адреса, - поэтому мы хотим убедиться, что ключ уникален.
- Раз уж мы обрабатываем оба вышеупомянутых случая, мы восстановим кнопки в их нормальном состоянии с помощью следующего кода:
if (contacts.isEmpty()) {
nameLine->clear();
addressText->clear();
}
nameLine->setReadOnly(true);
addressText->setReadOnly(true);
addButton->setEnabled(true);
submitButton->hide();
cancelButton->hide();
}
На снимке экрана, приведенном ниже, показан объект QMessageBox используемый нами для вывода на экран информационных сообщений.
Функция cancel() восстанавливает детали последнего отображаемого контакта и активирует кнопку addButton, а также скрывает кнопки submitButton и cancelButton.
void AddressBook::cancel()
{
nameLine->setText(oldName);
nameLine->setReadOnly(true);
addressText->setText(oldAddress);
addressText->setReadOnly(true);
addButton->setEnabled(true);
submitButton->hide();
cancelButton->hide();
}
Основная идея добавления контакта заключается в том, чтобы предоставить пользователю возможность выбора для щелчка по Submit или Cancel в любой момент. Блок-схема ниже поможет объяснить эту идею:
[Предыдущий: Адресная книга. Урок 1 - Проектирование пользовательского интерфейса] [Содержание] [Следующий: Урок 3]
Copyright © 2009 Nokia Corporation and/or its subsidiary(-ies) |
Торговые марки |
Qt 4.5.3 |
|