[Предыдущий: Адресная книга. Урок 3 - Навигация по записям] [Содержимое] [Следующий: Урок 5]
Адресная книга. Урок 4 - Редактирование и удаление адресов
Файлы:
На этом уроке мы рассмотрим пути модификации содержимого контактов, сохраняемых в приложении адресной книги.
Теперь мы имеем адресную книгу, которая не только содержит контакты в упорядоченном виде, но и позволяет перемещаться по ним. Будет удобно включить функции редактирования и удаления для того, чтобы можно при необходимости изменять детали контактов. Однако это требует небольшого усовершенствования, в виде перечислений. В предыдущих уроках мы имели два режима: AddingMode и NavigationMode - но они не были описаны как перечисления. Вместо этого мы включали и отключали соответствующие кнопки вручную, имея результатом множество строк повторяющегося кода.
В этом уроке мы определим перечисление Mode с тремя различными значениями:
- NavigationMode,
- AddingMode, и
- EditingMode.
Определение класса AddressBook
Обновляем файл addressbook.h с тем, чтобы он содержал перечисление Mode:
enum Mode { NavigationMode, AddingMode, EditingMode };
Мы также добавили к нашему списку открытых слотов два новых слота, editContact() и removeContact().
void editContact();
void removeContact();
Для того, чтобы переключаться между режимами мы ввели функцию updateInterface(), управляющую включением и отключением всех объектов класса QPushButton. Мы также добавили две новые кнопки, editButton и removeButton, для функций редактирования и удаления, обсуждаемых ранее.
void updateInterface(Mode mode);
...
QPushButton *editButton;
QPushButton *removeButton;
...
Mode currentMode;
В заключение, мы объявляем currentMode чтобы отслеживать текущий режим перечисления.
Реализация класса AddressBook
Теперь мы реализуем возможности изменения режима приложения адресной книги. Объекты кнопок editButton и removeButton по умолчанию создаются и отключаются, поскольку адресная книга начинает работу не имея контактов в памяти.
editButton = new QPushButton(tr("&Edit"));
editButton->setEnabled(false);
removeButton = new QPushButton(tr("&Remove"));
removeButton->setEnabled(false);
Затем мы соединяем эти кнопки с соответствующими слотами editContact() и removeContact(), и добавляем их к buttonLayout1.
connect(editButton, SIGNAL(clicked()), this, SLOT(editContact()));
connect(removeButton, SIGNAL(clicked()), this, SLOT(removeContact()));
...
buttonLayout1->addWidget(editButton);
buttonLayout1->addWidget(removeButton);
Функция editContact() сохраняет детали старого контакта в oldName и oldAddress, перед переключением в режим EditingMode. В этом режиме обе кнопки - и submitButton и cancelButton - включены, поэтому пользователь может изменить детали контакта и щелкнуть по любой из кнопок.
void AddressBook::editContact()
{
oldName = nameLine->text();
oldAddress = addressText->toPlainText();
updateInterface(EditingMode);
}
Функция submitContact() разделена на две части с помощью оператора if-else. Мы проверяем currentMode чтобы выяснить, не находится ли он в режиме AddingMode. Если это так, то мы продолжаем наш процесс добавления.
void AddressBook::submitContact()
{
...
if (currentMode == AddingMode) {
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));
}
В противном случае, мы проверяем currentMode - не равен ли он EditingMode. Если это так, мы сравниваем oldName и name. Если имя изменилось, мы удаляем из contacts старый контакт и вставляем только что исправленный контакт.
} else if (currentMode == EditingMode) {
if (oldName != name) {
if (!contacts.contains(name)) {
QMessageBox::information(this, tr("Edit Successful"),
tr("\"%1\" has been edited in your address book.").arg(oldName));
contacts.remove(oldName);
contacts.insert(name, address);
} else {
QMessageBox::information(this, tr("Edit Unsuccessful"),
tr("Sorry, \"%1\" is already in your address book.").arg(name));
}
} else if (oldAddress != address) {
QMessageBox::information(this, tr("Edit Successful"),
tr("\"%1\" has been edited in your address book.").arg(name));
contacts[name] = address;
}
}
updateInterface(NavigationMode);
}
Если был изменен только адрес (т.е., oldAddress не равен address), мы обновляем адрес контакта. В заключение, мы устанавливаем currentMode в значение NavigationMode. Это важный шаг, поскольку он снова включает все отключенные кнопки.
Чтобы удалить контакт из адресной книги, мы реализуем функцию removeContact(). Эта функция проверяет существует ли контакт в contacts.
void AddressBook::removeContact()
{
QString name = nameLine->text();
QString address = addressText->toPlainText();
if (contacts.contains(name)) {
int button = QMessageBox::question(this,
tr("Confirm Remove"),
tr("Are you sure you want to remove \"%1\"?").arg(name),
QMessageBox::Yes | QMessageBox::No);
if (button == QMessageBox::Yes) {
previous();
contacts.remove(name);
QMessageBox::information(this, tr("Remove Successful"),
tr("\"%1\" has been removed from your address book.").arg(name));
}
}
updateInterface(NavigationMode);
}
Если существует, то мы выводим на экран QMessageBox, чтобы пользователь подтвердил удаление. Как только пользователь подтвердит, мы вызываем previous() чтобы убедиться, что пользовательский интерфейс показывает другой контакт, и удаляем контакт, используя функцию класса QMap - remove(). В качестве вежливости мы выводим на экран QMessageBox, чтобы проинформировать пользователя. Оба окна сообщения используются в функции, показанной ниже:
Обновление пользовательского интерфейса
Ранее мы упоминали функцию updateInterface() как средство включения и отключения кнопок в зависимости от текущего режима. Функция обновляет текущий режим согласно переданного в нее аргумента mode, присваивая его переменной currentMode перед проверкой значения.
Все кнопки затем либо отключается либо включается в зависимости от текущего режима. Код для AddingMode и EditingMode показаны ниже:
void AddressBook::updateInterface(Mode mode)
{
currentMode = mode;
switch (currentMode) {
case AddingMode:
case EditingMode:
nameLine->setReadOnly(false);
nameLine->setFocus(Qt::OtherFocusReason);
addressText->setReadOnly(false);
addButton->setEnabled(false);
editButton->setEnabled(false);
removeButton->setEnabled(false);
nextButton->setEnabled(false);
previousButton->setEnabled(false);
submitButton->show();
cancelButton->show();
break;
Однако для режима NavigationMode мы включили условия внутри параметров функции QPushButton::setEnabled(). Это сделано для того, чтобы убедиться что кнопки editButton и removeButton включены когда в адресной книге имеется не менее одного контакта; nextButton и previousButton включены только если в адресной книге имеется более одного контакта.
case NavigationMode:
if (contacts.isEmpty()) {
nameLine->clear();
addressText->clear();
}
nameLine->setReadOnly(true);
addressText->setReadOnly(true);
addButton->setEnabled(true);
int number = contacts.size();
editButton->setEnabled(number >= 1);
removeButton->setEnabled(number >= 1);
nextButton->setEnabled(number > 1);
previousButton->setEnabled(number >1 );
submitButton->hide();
cancelButton->hide();
break;
}
}
При выполнении задачи установки режима и обновления пользовательского интерфейса в одной функции мы избегаем вероятности произвести "рассинхронизацию" пользовательского интерфейса с внутренним состоянием приложения.
[Предыдущий: Адресная книга. Урок 3 - Навигация по записям] [Содержимое] [Следующий: Урок 5]
Copyright © 2009 Nokia Corporation and/or its subsidiary(-ies) |
Торговые марки |
Qt 4.5.3 |
|