Саммерфилд Марк - QT 4: программирование GUI на С++ стр 16.

Шрифт
Фон

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

Во втором аргументе задается название диалогового окна. В третьем аргументе задается каталог начала просмотра файлов; в нашем случае это будет текущий каталог.

Четвертый аргумент определяет фильтры файлов. Фильтр файла состоит из описательной части и образца поиска. Если допустить поддержку не только родного формата файлов приложения Электронная таблица, а также формата файлов с запятой в качестве разделителя и файлов 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() уведомит пользователя о возникшей проблеме, выдав соответствующее сообщение. В целом полезно предусматривать выдачу сообщений об ошибках в компонентах низкого уровня, поскольку они могут обеспечить получение точной информации о причинах ошибки.

В обоих случаях мы будем выдавать сообщение в строке состояния в течение 2 секунд (2000 миллисекунд) для того, чтобы пользователь знал о выполняемых приложением действиях.

01 bool MainWindow::save()

02 {

03 if (curFile.isEmpty()) {

04 return saveAs();

05 } else {

06 return saveFile(curFile);

07 }

08 }

09 bool MainWindow::saveFile(const QString &fileName)

10 {

11 if (!spreadsheet->writeFile(fileName)) {

12 statusBar()->showMessage(tr("Saving canceled"), 2000);

13 return false;

14 }

15 setCurrentFile(fileName);

16 statusBar()->showMessage(tr("File saved"), 2000);

17 return true;

18 }

Слот save() соответствует пункту меню File | Save. Если файл уже имеет имя, потому что уже открывался до этого или уже сохранялся, слот save() вызывает saveFile(), задавая это имя; в противном случае он просто вызывает saveAs().

01 bool MainWindow::saveAs()

02 {

03 QString fileName = QFileDialog::getSaveFileName(this,

04 tr("SaveSpreadsheet"),

05 tr("Spreadsheet files (*.sp)"));

06 if (fileName.isEmpty())

07 return false;

08 return saveFile(fileName);

09 }

Слот saveAs() соответствует пункту меню File | Save As. Мы вызываем QFileDialog::getSaveFileName() для получения имени файла от пользователя. Если пользователь нажимает кнопку Cancel, мы возвращаем значение false, которое передается дальше вплоть до вызвавшей функции (save() или okToContinue() ).

Если файл с данным именем уже существует, функция getSaveFileName() попросит пользователя подтвердить его перезапись. Такое поведение можно предотвратить, передавая функции getSaveFileName() дополнительный аргумент QFileDialog::DontConfirmOverwrite.

01 void MainWindow::closeEvent(QCloseEvent *event)

02 {

03 if (okToContinue()) {

04 writeSettings();

05 event->accept();

06 } else {

07 event->ignore();

08 }

09 }

Когда пользователь выбирает пункт меню File | Exit или щелкает по кнопке X заголовка окна, вызывается слот QWidget::close(). В результате будет сгенерировано событие виджета «close» (закрытие). Переопределяя функцию QWidget::closeEvent(), мы можем перехватывать команды по закрытию главного окна и принимать решения относительно возможности его фактического закрытия.

Если изменения не сохранены

подробно рассматриваются такие классыконтейнеры, как QStringList, и их связь со стандартной библиотекой шаблонов С++ (Standard Template Library STL), a также применение в Qt классов итераторов в стиле Java.

Затем мы снова проходим по списку файла, на этот раз пользуясь индексацией массива. Для каждого файла мы создаем строку из амперсанда, номера файла (j + 1), пробела и имени файла (без пути). Для соответствующего пункта меню мы задаем этот текст. Например, если первым был файл С:\My Documents\tab04.sp, пункт меню первого недавно используемого файла будет иметь текст «&1 tab04.sp».

Рис. 3.11. Меню File со списком файлов, которые открывались недавно.

С каждым пунктом меню recentFileActions может быть связан элемент данных «data» типа QVariant. Тип QVariant может хранить многие типы С++ и Qt; он рассматривается в гл. 11. Здесь в элементе меню «data» мы храним полное имя файла, чтобы позже можно было легко его найти. Мы также делаем этот пункт меню видимым.

Если пунктов меню (массив recentFileActions ) больше, чем недавно открытых файлов (массив recentFiles ), мы просто не отображаем дополнительные пункты. Наконец, если существует по крайней мере один недавно используемый файл, мы делаем разделитель видимым.

Ваша оценка очень важна

0
Шрифт
Фон

Помогите Вашим друзьям узнать о библиотеке