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

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

Жанры

QT 4: программирование GUI на С++

Саммерфилд Марк

Шрифт:

20 (dialog.tertiaryOrderCombo->currentIndex == 0);

21 spreadsheet->sort(compaге);

22 }

23 }

Порядок действий при программировании функции sort аналогичен порядку действий, применяемому при программировании функции goToCell;

• мы создаем диалоговое окно в стеке и инициализируем его;

• мы вызываем диалоговое окно при помощи функции exec;

• если пользователь нажимает кнопку OK, мы используем введенные пользователем в диалоговом окне значения соответствующим образом.

Вызов setColumnRange

задает столбцы, выбранные для сортировки. Например, при выделении области, показанной на рис. 3.14, функция range.leftColumn возвратит 0, давая в результате 'A' + 0 = 'A', a range.rightColumn возвратит 2, давая в результате 'A' + 2 = 'C'.

В объекте compare хранятся первичный, вторичный и третичный ключи, а также порядок сортировки по ним. (Определение класса SpreadsheetCompare мы рассмотрим в следующей главе.) Этот объект используется функцией Spreadsheet::sort для сортировки строк. В массиве keys содержатся номера столбцов ключей. Например, если выбрана область с C2 по E5, то столбец С будет иметь индекс 0. В массиве ascending в переменных типа bool хранятся значения направления сортировки для каждого ключа. Функция QComboBox::currentIndex возвращает индекс текущего элемента (начиная с 0). Для вторичного и третичного ключей мы вычитаем единицу из текущего элемента, чтобы учесть значения «None» (отсутствует).

Функция sort сделает свою работу, но она не совсем надежна. Она предполагает определенный способ реализации диалогового окна, а именно использование выпадающих списков и элементов со значением «None». Это означает, что при изменении дизайна диалогового окна Sort нам, возможно, потребуется изменить также программный код. Такой подход можно использовать для диалогового окна, применяемого только в одном месте; однако это может вызвать серьезные проблемы сопровождения, если это диалоговое окно станет использоваться в различных местах.

Более надежным будет такой подход, когда класс SortDialog делается более «разумным» и может создавать свой собственный объект SpreadsheetCompare, доступный вызывающему его компоненту. Это значительно упрощает функцию MainWindow::sort:

01 void MainWindow::sort

02 {

03 SortDialog dialog(this);

04 QTableWidgetSelectionRange range = spreadsheet->selectedRange;

05 dialog.setColumnRange('A' + range.leftColumn,

06 'А' + range.rightColumn);

07 if (dialog.exec)

08 spreadsheet->performSort(dialog.comparisonObject);

09 }

Такой подход приводит к созданию слабо связанных компонентов, и выбор его почти всегда будет правилен для диалоговых окон, которые вызываются из нескольких мест.

Более «радикальный» подход мог бы заключаться в передаче указателя на объект Spreadsheet при инициализации объекта SortDialog и разрешении диалоговому окну работать непосредственно с объектом Spreadsheet. Это значительно снизит универсальность диалогового окна SortDialog, поскольку оно будет работать только с виджетами определенного типа, но это позволит еще больше упростить программу из-за возможности исключения функции SortDialog::setColumnRange. В этом случае функция MainWindow::sort примет следующий

вид:

01 void MainWindow::sort

02 {

03 SortDialog dialog(this);

04 dialog.setSpreadsheet(spreadsheet);

05 dialog.exec;

06 }

Этот подход является зеркальным отражением первого: вместо знания вызывающим компонентом характерных особенностей диалогового окна теперь само диалоговое окно должно иметь представление об особенностях структур данных, передаваемых вызывающим компонентом. Этот подход полезно применять, когда диалоговому окну требуется отслеживать изменения. В то время как при первом подходе ненадежен код вызвавшего компонента, третий подход перестает работать при изменении структуры данных.

Некоторые разработчики выбирают один из подходов и всегда следуют ему. При этом разработка диалоговых окон становится более привычным и простым делом, однако достоинства других подходов не будут использованы. В идеале решение по выбору конкретного подхода должно учитывать в каждом случае особенности конкретного диалогового окна.

Мы завершим данный раздел созданием диалогового окна About (справка о программе). Мы могли бы создать для представления данных о программе специальное диалоговое окно наподобие созданных нами ранее Find или Go-to-Cell, но поскольку диалоговые окна About сильно стилизованы, в средствах разработки Qt предусмотрено простое решение:

01 void MainWindow::about

02 {

03 QMessageBox::about(this, tr("About Spreadsheet"),

04 tr("<h2>Spreadsheet 1.1</h2>"

05 "Copyright &copy; 2006 Software Inc."

06 "Spreadsheet is a small application that "

07 "demonstrates QAction, QMainWindow, QMenuBar, "

08 "QStatusBar, QTableWidget, QToolBar, and many other "

09 "Qt classes."));

10 }

Рис. 3.15. Справка о приложении Электронная таблица.

Диалоговое окно About получается путем вызова удобной статической функции QMessageBox::about. Эта функция очень напоминает функцию QMessageBox::warning, однако здесь вместо стандартных «предупреждающих» пиктограмм используется пиктограмма родительского окна.

Таким образом, мы уже сумели воспользоваться несколькими удобными статическими функциями, определенными в классах QMessageBox и QFileDialog. Эти функции создают диалоговое окно, инициализируют его и вызывают для него функцию exec. Кроме того, вполне возможно, хотя и менее удобно, создать виджет QMessageBox или QFileDialog так же, как это делается для любого другого виджета, и явно вызвать для него функцию exec или даже show.

Сохранение настроек приложения

В конструкторе MainWindow мы уже вызывали функцию readSettings для загрузки сохраненных приложением настроек. Аналогично в функции closeEvent мы вызывали writeSettings для сохранения настроек. Эти функции являются последними функциями—членами MainWindow, которые необходимо реализовать.

01 void MainWindow::writeSettings

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

Моя на одну ночь

Тоцка Тала
Любовные романы:
современные любовные романы
короткие любовные романы
5.50
рейтинг книги
Моя на одну ночь

Черный Маг Императора 8

Герда Александр
8. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Черный Маг Императора 8

Измена. Отбор для предателя

Лаврова Алиса
1. Отбор для предателя
Фантастика:
фэнтези
5.00
рейтинг книги
Измена. Отбор для предателя

Кодекс Крови. Книга II

Борзых М.
2. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга II

Шаг в бездну

Муравьёв Константин Николаевич
3. Перешагнуть пропасть
Фантастика:
фэнтези
космическая фантастика
7.89
рейтинг книги
Шаг в бездну

Часовая битва

Щерба Наталья Васильевна
6. Часодеи
Детские:
детская фантастика
9.38
рейтинг книги
Часовая битва

Вечная Война. Книга II

Винокуров Юрий
2. Вечная война.
Фантастика:
юмористическая фантастика
космическая фантастика
8.37
рейтинг книги
Вечная Война. Книга II

Хроники странного королевства. Вторжение. (Дилогия)

Панкеева Оксана Петровна
110. В одном томе
Фантастика:
фэнтези
9.38
рейтинг книги
Хроники странного королевства. Вторжение. (Дилогия)

Часовой ключ

Щерба Наталья Васильевна
1. Часодеи
Фантастика:
фэнтези
9.36
рейтинг книги
Часовой ключ

Инвестиго, из медика в маги

Рэд Илья
1. Инвестиго
Фантастика:
фэнтези
городское фэнтези
попаданцы
5.00
рейтинг книги
Инвестиго, из медика в маги

Кротовский, может, хватит?

Парсиев Дмитрий
3. РОС: Изнанка Империи
Фантастика:
попаданцы
альтернативная история
аниме
7.50
рейтинг книги
Кротовский, может, хватит?

Драконий подарок

Суббота Светлана
1. Королевская академия Драко
Любовные романы:
любовно-фантастические романы
7.30
рейтинг книги
Драконий подарок

Очешуеть! Я - жена дракона?!

Амеличева Елена
Фантастика:
юмористическая фантастика
5.43
рейтинг книги
Очешуеть! Я - жена дракона?!

Идеальный мир для Лекаря 9

Сапфир Олег
9. Лекарь
Фантастика:
боевая фантастика
юмористическое фэнтези
6.00
рейтинг книги
Идеальный мир для Лекаря 9