- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
QT 4: программирование GUI на С++ - Жасмин Бланшет
Шрифт:
Интервал:
Закладка:
14 updateStatusBar();
15 }
Функция QMainWindow::statusBar() возвращает указатель на строку состояния. (Строка состояния создается при первом вызове функции statusBar.) В качестве индикаторов состояния просто используются текстовые метки QLabel, текст которых изменяется по мере необходимости. Мы добавили отступ для formulaLabel, чтобы указанный здесь текст отображался с небольшим смещением от левого края. При добавлении текстовых меток QLabel в строку состояния они автоматически становятся дочерними по отношению к строке состояния.
Рис. 3.8 показывает, что эти две текстовые метки занимают различное пространство. Индикатор ячейки занимает очень немного места, и при изменении размеров окна дополнительное пространство будет использовано для правого индикатора, где отображается формула ячейки. Это достигается путем установки фактора растяжения на 1 при вызове функции QStatusBar::addWidget() для формулы ячейки при создании двух других индикаторов. Для индикатора позиции фактор растяжения по умолчанию равен 0, и поэтому он не будет растягиваться.
Рис. 3.8. Строка состояния приложения Электронная таблица.
Когда QStatusBar располагает виджеты индикаторов, он постарается обеспечить «идеальный» размер виджетов, заданный функцией QWidget::sizeHint(), и затем растянет виджеты, которые допускают растяжение, заполняя дополнительное пространство. Идеальный размер виджета зависит от его содержания и будет сам изменяться по мере изменения содержания. Чтобы предотвратить постоянное изменение размера индикатора ячейки, мы устанавливаем его минимальный размер на значение, достаточное для размещения в нем самого большого возможного текстового значения («W999»), и добавляем еще немного пространства. Мы также устанавливаем его параметр выравнивания на значение AlignHCenter для выравнивания по центру текста в области индикатора.
Перед завершением функции мы соединяем два сигнала Spreadsheet с двумя слотами главного окна MainWindow: updateStatusBar() и spreadsheetModified().
01 void MainWindow::updateStatusBar()
02 {
03 locationLabel->setText(spreadsheet->currentLocation());
04 formulaLabel->setText(spreadsheet->currentFormula());
05 }
Слот updateStatusBar() обновляет индикаторы расположения ячейки и формулы ячейки. Он вызывается при любом перемещении пользователем курсора ячейки на новую ячейку. В конце функции createStatusBar() этот слот используется как обычная функция для инициализации индикаторов. Это необходимо, поскольку Spreadsheet при запуске не генерирует сигнал currentCellChanged().
06 void MainWindow::spreadsheetModified()
07 {
08 setWindowModified(true);
09 updateStatusBar();
10 }
Слот spreadsheetModified() обновляет все три индикатора для отражения ими текущего состояния приложения и устанавливает переменную modified на значение true. (Мы использовали переменную modified при реализации меню File для контроля несохраненных изменений.) Слот spreadsheetModified() устанавливает свойство windowModified в значение true, обновляя строку заголовка. Эта функция обновляет также индикаторы расположения и формулы ячейки, чтобы они отражали текущее состояние.
Реализация меню File
В данном разделе мы определим слоты и закрытые функции, необходимые для обеспечения работы меню File и для управления списком недавно используемых файлов.
01 void MainWindow::newFile()
02 {
03 if (okToContinue ())
04 {
05 spreadsheet->clear();
06 setCurrentFile("");
07 }
08 }
Слот newFile() вызывается при выборе пользователем пункта меню File | New или при нажатии кнопки New на панели инструментов. Закрытая функция okToContinue() задает пользователю вопрос относительно необходимости сохранения изменений («Do you want to save your changes?» — Сохранить изменения?), если изменения до этого не были сохранены. Она возвращает значение true, если пользователь отвечает Yes или No (сохраняя документ при ответе Yes), и она возвращает значение false, если пользователь отвечает Cancel. Функция Spreadsheet::clear() очищает все ячейки и формулы электронной таблицы. Закрытая функция setCurrentFile() кроме установки закрытой переменной curFile и обновления списка недавно используемых файлов изменяет заголовок окна, отражая тот факт, что редактируемый документ не имеет заголовка.
01 bool MainWindow::okToContinue()
02 {
03 if (isWindowModified()) {
04 int r = QMessageBox::warning(this,
05 tr("Spreadsheet"), tr("The document has been modified.n"
06 "Do you want to save your changes?"),
07 QMessageBox::Yes | QMessageBox::Default,
08 QMessageBox::No,
09 QMessageBox::Cancel | QMessageBox::Escape);
10 if (r == QMessageBox::Yes) {
11 return save();
12 } else if (r == QMessageBox::Cancel) {
13 return false;
14 }
15 }
16 return true;
17 }
B okToContinue() мы проверяем свойство windowModified. Если оно имеет значение true, мы выводим на экран сообщение, показанное на рис. 3.9. Окно сообщения содержит кнопки Yes, No и Cancel. Модификатор QMessageBox::Default делает Yes кнопкой, которая выбирается по умолчанию. Модификатор QMessageBox::Escape задает клавишу Esc в качестве синонима кнопки Cancel.
Рис. 3.9. «Сохранить изменения?»
Вызов функции warning() на первый взгляд может показаться слишком сложным, но он имеет очень простой формат:
QMessageBox::warning(родительский объект, заголовок, сообщение, кнопка0, кнопка1, …);
QMessageBox содержит функции information(), question() и critical(), каждая из которых имеет собственную пиктограмму.
Рис. 3.10. Пиктограммы окна сообщения.
01 void MainWindow::open()
02 {
03 if (okToContinue()) {
04 QString fileName = QFileDialog::getOpenFileName(".", fileFilters, this);
05 if (!fileName.isEmpty())
06 loadFile(fileName);
07 }
08 }
Слот open() соответствует пункту меню File | Open. Как и слот newFile(), он сначала вызывает okToContinue() для обработки несохраненных изменений. Затем он вызывает удобную статическую функцию QFileDialog::getOpenFileName() для получения от пользователя нового имени файла. Эта функция выводит на экран диалоговое окно для выбора пользователем файла и возвращает имя файла или пустую строку при нажатии пользователем клавиши Cancel.
В первом аргументе функции QFileDialog::getOpenFileName() задается родительский виджет. Взаимодействие родительских и дочерних объектов для диалоговых окон и для других виджетов будет различно. Диалоговое окно всегда является самостоятельным окном, однако если у него имеется родитель, то оно размещается по умолчанию в верхней части родительского объекта. Кроме того, дочернее диалоговое окно использует панель задач родительского объекта.
Во втором аргументе задается название диалогового окна. В третьем аргументе задается каталог начала просмотра файлов; в нашем случае это будет текущий каталог.
Четвертый аргумент определяет фильтры файлов. Фильтр файла состоит из описательной части и образца поиска. Если допустить поддержку не только родного формата файлов приложения Электронная таблица, а также формата файлов с запятой в качестве разделителя и файлов Lotus 1-2-3, нам пришлось бы инициализировать переменные следующим образом:
tr("Spreadsheet files (*.sp)n"
"Comma-separated values files (*.csv)n"
"Lotus 1-2-3 files (*.wk1 *.wks)")
Закрытая функция loadFile() вызвана в open() для загрузки файла. Мы делаем эту функцию независимой, поскольку нам потребуется выполнить те же действия для загрузки файлов, которые открывались недавно:
01 bool MainWindow::loadFile(const QString &fileName)
02 {
03 if (!spreadsheet->readFile(fileName)) {
04 statusBar()->showMessage(tr("Loading canceled"), 2000);
05 return false;
06 }
07 setCurrentFile(fileName);
08 statusBar()->showMessage(tr("File loaded"), 2000);
09 return true;
10 }
Мы используем функцию Spreadsheet::readFile() для чтения файла с диска. Если загрузка завершилась успешно, мы вызываем функцию setCurrentFile() для обновления заголовка окна; в противном случае функция Spreadsheet::readFile() уведомит пользователя о возникшей проблеме, выдав соответствующее сообщение. В целом полезно предусматривать выдачу сообщений об ошибках в компонентах низкого уровня, поскольку они могут обеспечить получение точной информации о причинах ошибки.

