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

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

Жанры

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

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

Шрифт:

Мы модифицируем приложение Электронная таблица для обеспечения возможности работы со многими документами. Для начала нам потребуется немного видоизменить меню File:

• пункт меню File | New создает новое главное окно с пустым документом вместо повторного использования существующего главного окна;

• пункт меню File | Close закрывает текущее главное окно;

• пункт меню File | Exit закрывает все окна.

Рис. 3.16. Новое меню File.

В первоначальной версии меню File

не было пункта Close (закрыть), поскольку он выполнял бы ту же функцию, что и пункт меню Exit. Новая функция main примет следующий вид:

01 int main(int argc, char *argv[])

02 {

03 QApplication app(argc, argv);

04 MainWindow *mainWin = new MainWindow;

05 mainWin->show;

06 return app.exec;

07 }

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

Новый слот MainWindow::newFile будет выглядеть следующим образом:

01 void MainWindow::newFile

02 {

03 MainWindow *mainWin = new MainWindow;

04 mainWin->show;

05 }

Мы просто создаем новый экземпляр MainWindow. Может показаться странным, что мы нигде не сохраняем указатель на новое окно, но это не составит проблемы, поскольку Qt отслеживает все окна.

Действия Close и Exit будут задаваться следующим образом:

01 void MainWindow::createActions

02 {

03 closeAction = new QAction(tr("&Close"), this);

04 closeAction->setShortcut(tr("Ctrl+W"));

05 closeAction->setStatusTip(tr("Close this window"));

06 connect(closeAction, SIGNAL(triggered), this, SLOT(close));

07 exitAction = new QAction(tr("E&xit"), this);

08 exitAction->setShortcut(tr("Ctrl+Q"));

09 exitAction->setStatusTip(tr("Exit the application"));

10 connect(exitAction, SIGNAL(triggered),

11 qApp, SLOT(closeAllWindows));

12 }

Слот closeAllWindows объекта QApplication закрывает все окна приложения, если только никакое из них не отклоняет запрос (event) на его закрытие. Именно такой режим работы нам здесь нужен. Нам не надо беспокоиться о несохраненных изменениях, поскольку обработка этого события выполняется функцией MainWindow::closeEvent при каждом закрытии окна.

Можно подумать, что на этом завершается построение приложения, работающего со многими документами. К сожалению, одна проблема оказалась незамеченной. Если пользователь будет постоянно создавать и закрывать главные

окна, в конце концов может не хватить памяти компьютера. Это происходит из-за того, что мы создаем виджеты MainWindow в функции newFile, но никогда не удаляем их. Когда пользователь закрывает главное окно, оно исчезает с экрана, но по-прежнему остается в памяти. При создании многих окон может возникнуть проблема.

Решение состоит в установке признака Qt::WA_DeleteOnClose в конструкторе:

01 MainWindow::MainWindow

02 {

03 setAttribute(Qt::WA_DeleteOnClose);

04 }

Это указывает Qt на необходимость удаления окна при его закрытии. Кроме Qt::WA_DeleteOnClose в конструкторе QWidget можно устанавливать много других флажков, задавая необходимый режим работы виджета.

Утечка памяти — не единственная проблема, с которой мы можем столкнуться. В нашем первоначальном проекте приложения подразумевалось, что у нас будет только одно главное окно. При работе со многими окнами каждое главное окно будет иметь свой список файлов, открывавшихся последними, и свои параметры работы. Очевидно, что список последних открывавшихся файлов должен относиться ко всему приложению. Это можно обеспечить очень просто путем объявления статической переменной recentFiles, и тогда во всем приложении будет только один ее экземпляр. Но здесь мы должны обеспечить при каждом вызове функции updateRecentFileActions для обновления меню File вызов ее для всех главных окон. Это выполняет следующий программный код:

foreach (QWidget *win, QApplication::topLevelWidgets) {

if (MainWindow *mainWin = qobject_cast<MainWindow *>(win))

mainWin->updateRecentFileActions;

}

Здесь используется конструкция Qt foreach (она рассматривается в главе 11 ) для прохода по всем имеющимся в приложении виджетам и делается вызов функции updateRecentFileItems для всех виджетов типа MainWindow. Аналогичным образом можно синхронизировать установку опций ShowGrid и Auto—Recalculate или убедиться в том, что не загружены два файла с одинаковым именем.

Рис. 3.17. Однодокументный и многодокументный интерфейсы.

Приложения, обеспечивающие работу с одним документом в главном окне, называются приложениями с однодокументным интерфейсом (SDI — single document interface). Распространенной альтернативой ему в Windows стал многодокументный интерфейс (MDI — multiple document interface), когда приложение имеет одно главное окно, в центральной области которого могут находиться окна многих документов. С помощью средств разработки Qt можно создавать как приложения SDI, так и приложения MDI на всех поддерживаемых платформах. На рис. 3.17 показан вид приложения Электронная таблица при использовании обоих подходов. Интерфейс MDI рассматривается в главе 6 («Управление компоновкой»).

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

Государь

Кулаков Алексей Иванович
3. Рюрикова кровь
Фантастика:
мистика
альтернативная история
историческое фэнтези
6.25
рейтинг книги
Государь

Волкодав

Семёнова Мария Васильевна
1. Волкодав
Фантастика:
фэнтези
героическая фантастика
9.46
рейтинг книги
Волкодав

Кодекс Охотника. Книга XV

Винокуров Юрий
15. Кодекс Охотника
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга XV

Жена неверного ректора Полицейской академии

Удалова Юлия
Любовные романы:
любовно-фантастические романы
4.25
рейтинг книги
Жена неверного ректора Полицейской академии

Зодчий. Книга V

Погуляй Юрий Александрович
5. Зодчий Империи
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Зодчий. Книга V

Я все еще граф. Книга IX

Дрейк Сириус
9. Дорогой барон!
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Я все еще граф. Книга IX

Весь цикл «Десантник на престоле». Шесть книг

Ланцов Михаил Алексеевич
Десантник на престоле
Фантастика:
альтернативная история
8.38
рейтинг книги
Весь цикл «Десантник на престоле». Шесть книг

Телохранитель Генсека. Том 2

Алмазный Петр
2. Медведев
Фантастика:
попаданцы
альтернативная история
6.25
рейтинг книги
Телохранитель Генсека. Том 2

Сапер

Вязовский Алексей
1. Сапер
Фантастика:
героическая фантастика
попаданцы
альтернативная история
5.29
рейтинг книги
Сапер

Развод в 45. От любви до ненависти

Гофман Крис
6. Развод
Любовные романы:
остросюжетные любовные романы
5.40
рейтинг книги
Развод в 45. От любви до ненависти

Ваше Сиятельство 4т

Моури Эрли
4. Ваше Сиятельство
Любовные романы:
эро литература
5.00
рейтинг книги
Ваше Сиятельство 4т

Российские фантасмагории (сборник)

Булгаков Михаил Афанасьевич
Юмор:
юмористическая проза
5.00
рейтинг книги
Российские фантасмагории (сборник)

Демон-хранитель

TsissiBlack
Фантастика:
фэнтези
мистика
5.20
рейтинг книги
Демон-хранитель

Наномашины, внучок! Том 2

Новиков Николай Васильевич
2. Чего смотришь? Иди книгу читай
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Наномашины, внучок! Том 2