The OpenNET Project / Index page

[ новости /+++ | форум | wiki | теги | ]

Каталог документации / Раздел "Программирование, языки" / Оглавление документа

Глава 3. Создание главного окна приложения

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

Рисунок 3.1. Приложение -- электронная таблица.


Главное окно -- это своего рода каркас, на который "натягивается" весь пользовательский интерфейс приложения. Здесь мы рассмотрим пример создания главного окна электронной таблицы. Внешний вид нашего будущего приложения приводится на рисунке 3.1. В этом приложении мы будем использовать диалоги "Find", "Go-to-Cell" и "Sort", которые были созданы нами в Главе 2.

Внутри большинства приложений с графическим интерфейсом "прячется" код, который обеспечивает основные функциональные возможности программы, например, работа с файлами или обработка данных, представляемых пользовательским интерфейсом. В Главе 4 мы покажем -- как реализуется такого рода функциональность, на примере нашей электронной таблицы.

3.1. Создание класса-наследника от QMainWindow.

Главное окно любого приложения -- это класс-наследник QMainWindow. Большинство приемов, используемых при создания диалогов и о которых мы говорили в Главе 2, вполне применимы и при создании главного окна приложения.

Главное окно может быть создано в Qt Designer, но мы все будем делать "вручную", чтобы продемонстрировать процесс создания главного окна во всех деталях. Если вы предпочитаете визуальное проектирование -- прочитайте главу "Creating a Main Window Application" в справочном руководстве к Qt Designer.

Исходные тексты главного окна будут располагаться в двух файлах: mainwindow.cpp и mainwindow.cpp. Начнем с файла заголовка:

#ifndef MAINWINDOW_H 
#define MAINWINDOW_H 
#include <qmainwindow.h> 
#include <qstringlist.h> 
class QAction; 
class QLabel; 
class FindDialog; 
class Spreadsheet; 

class MainWindow : public QMainWindow 
{ 
  Q_OBJECT 
public: 
  MainWindow(QWidget *parent = 0, const char *name = 0); 

protected: 
  void closeEvent(QCloseEvent *event); 
  void contextMenuEvent(QContextMenuEvent *event);      
      
Это определение класса MainWindow -- наследника QMainWindow. Оно содержит макрос Q_OBJECT, поскольку реализует свои собственные сигналы и слоты.

Функция closeEvent(), в классе QWidget, объявлена как виртуальная. Она автоматически вызывается перед завершением приложения. Мы перекрываем ее в MainWindow для того, чтобы иметь возможность спросить у пользователя -- желает ли он сохранить произведенные изменения, а также для того, чтобы сохранить на диск пользовательские настройки.

Аналогично, функция contextMenuEvent() вызывается, когда пользователь щелкает правой кнопкой мыши по виджету. Мы перекрываем ее в MainWindow для того, чтобы вывести контекстное меню.

private slots: 
  void newFile();
  void open(); 
  bool save(); 
  bool saveAs(); 
  void find(); 
  void goToCell(); 
  void sort(); 
  void about();     
      
Реализация действий некоторых пунктов меню, таких как File|New и Help|About, выполнена в виде приватных слотов MainWindow. Большинство слотов имеют тип void, но слоты save() и saveAs возвращают результат типа bool. Значение, возвращаемое слотом, игнорируется в случае вызова по сигналу, но когда слот вызывается как обычная функция, то мы получаем от него возвращаемое значение, которое можем использовать для своих нужд.
  void updateCellIndicators(); 
  void spreadsheetModified(); 
  void openRecentFile(int param); 

private: 
  void createActions(); 
  void createMenus(); 
  void createToolBars(); 
  void createStatusBar(); 
  void readSettings(); 
  void writeSettings(); 
  bool maybeSave(); 
  void loadFile(const QString &fileName); 
  void saveFile(const QString &fileName); 
  void setCurrentFile(const QString &fileName); 
  void updateRecentFileItems(); 
  QString strippedName(const QString &fullFileName);      
      
Дополнительные приватные функции, необходимые для обслуживания пользовательского интерфейса.
  Spreadsheet *spreadsheet; 
  FindDialog *findDialog; 
  QLabel *locationLabel; 
  QLabel *formulaLabel; 
  QLabel *modLabel; 
  QStringList recentFiles; 
  QString curFile; 
  QString fileFilters; 
  bool modified; 
  
  enum { MaxRecentFiles = 5 }; 
  int recentFileIds[MaxRecentFiles]; 
  
  QPopupMenu *fileMenu; 
  QPopupMenu *editMenu; 
  QPopupMenu *selectSubMenu; 
  QPopupMenu *toolsMenu; 
  QPopupMenu *optionsMenu; 
  QPopupMenu *helpMenu; 
  QToolBar *fileToolBar; 
  QToolBar *editToolBar;
  QAction *newAct; 
  QAction *openAct; 
  QAction *saveAct; 
  ... 
  QAction *aboutAct; 
  QAction *aboutQtAct; 
}; 
#endif      
      
Кроме функций, класс главного окна имеет ряд скрытых переменных. Все они будут описаны по мере необходимости.

Теперь перейдем к реализации:

#include <qaction.h> 
#include <qapplication.h> 
#include <qcombobox.h> 
#include <qfiledialog.h> 
#include <qlabel.h> 
#include <qlineedit.h> 
#include <qmenubar.h> 
#include <qmessagebox.h> 
#include <qpopupmenu.h> 
#include <qsettings.h> 
#include <qstatusbar.h> 

#include "cell.h" 
#include "finddialog.h" 
#include "gotocelldialog.h" 
#include "mainwindow.h" 
#include "sortdialog.h" 
#include "spreadsheet.h"      
      
Здесь подключаются заголовки всех классов Qt, которые используются в приложении, а также заголовок класса главного окна и ряд других заголовочных файлов, таких как finddialog.h, gotocelldialog.h и sortdialog.h, которые мы создали в предыдущей главе.
  MainWindow::MainWindow(QWidget *parent, const char *name) 
    : QMainWindow(parent, name) 
  { 
    spreadsheet = new Spreadsheet(this); 
    setCentralWidget(spreadsheet); 
    createActions(); 
    createMenus(); 
    createToolBars(); 
    createStatusBar(); 
    readSettings(); 
    setCaption(tr("Spreadsheet")); 
    setIcon(QPixmap::fromMimeSource("icon.png")); 
    findDialog = 0; 
    fileFilters = tr("Spreadsheet files (*.sp)"); 
    modified = false; 
  }      
      
Конструктор начинается с создания виджета Spreadsheet, который будет центральным виджетом главного окна. Центральный виджет занимает все пространство, находящееся между панелью инструментов (toolbar) и строкой состояния (statusbar). Класс Spreadsheet является потомком класса QTable и добавляет некоторые свойства, характерные для электронных таблиц. Среди них можно назвать поддержку формул, которая будет реализована в Главе 4.

Рисунок 3.2. Раскладка виджетов в главном окне.


Далее вызываются приватные функции createActions(), createMenus(), createToolBars() и createStatusBar(), которые создают остальную часть главного окна. Для восстановления пользовательских настроек вызывается функция readSettings().

В качестве иконки приложения устанавливается icon.png. Qt поддерживает различные форматы графических файлов, включая BMP, GIF [1] , JPEG, MNG, PNG, PNM, XBM и XPM. Вызов QWidget::setIcon() выводит иконку в верхний левый угол окна. К сожалению, отсутствует платформо-независимый способ помещения иконки на рабочий стол.

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

В данном примере мы будем использовать механизм "коллекции изображений", поскольку работать с ним намного проще, чем загружать файлы в процессе исполнения. К тому же он может взаимодействовать со всеми, поддерживаемыми библиотекой, графическими форматами. Все изображения мы будем хранить в каталоге images. Чтобы создать файл на языке C++ (он будет создан утилитой uic), который будет хранить наши изображения, добавим следующие строки в файл .pro:

IMAGES = images/icon.png \ 
         images/new.png \ 
         images/open.png \ 
         ... 
         images/find.png \ 
         images/gotocell.png      
      
Изображения будут помещены в исполняемый файл приложения и могут быть получены вызовом QPixmap::fromMimeSource(). Преимущество такого способа организации хранения изображений заключается в том, что они никогда не потеряются, поскольку находятся внутри исполняемого файла.

Если главное окно создается в Qt Designer, то вы можете использовать визуальные средства, предоставляемые построителем, для вставки изображений в коллекцию.

Примечания

[1]

Если вы проживаете в стране, чье законодательство признает патенты на программное обеспечение и где компания Unisys имеет зарегистрированный патент на алгоритм сжатия LZW, то Unisys может потребовать от вас приобрести лицензию на использование GIF. По этой причине, поддержка формата GIF в Qt по-умолчанию запрещена. Мы полагаем, что срок действия этого патента по всему миру истечет к концу 2004 года.




Спонсоры:
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2021 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру