Next Previous Table of Contents

### 4. Главное окно приложения

При разработке приложения с графическим пользовательским интерфейсом наиболее трудоемкой является реализация так называемого элемента Просмотр ("view") приложения. Просмотр - это видимый элемент, который отображает данные, содержащиеся в обрабатываемом приложением документе, и предоставляет методы для изменения этих данных. Пользователь заставляет эти методы работать, порождая события клавиатуры и мыши; сложные операции часто выполняются с помощью команд, генерируемых при выборе пунктов меню или кнопок панели управления, которые взаимодействуют с Просмотром. Строка статуса предоставляет информацию о документе, о режиме работы объекта Просмотр и о состоянии приложения. Рассмотрим, например, как устроен текстовый редактор, и где реализованы его части.

Редактор обычно предназначен для просмотра и изменения текстового файла пользователем. Если вы откроете KEdit, вы увидите следующие элементы пользовательского интерфейса:

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

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

Для некоторых стандартных задач, например, текстовой обработки или отображения HTML файлов, Qt и библиотеки KDE предоставляют специальные объекты просмотра; мы обсудим некоторые аспекты использования таких объектов высокого уровня в следующем разделе. Но для большинства приложений должны быть разработаны новые элементы. Это момент, где программист становится также дизайнером, и где требуются его творческие способности. Однако не забывайте, что основное в пользовательском интерфейсе - это его интуитивность. Помните, что многие пользователи не воспримут приложение, которое:

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

Однако не стоит даже говорить, что основной критерий качества разработки - стабильность. Никто не сможет предотвратить все ошибки, но с помощью хорошо продуманного процесса разработки можно свести их число к минимуму. Четко определите цель и широко используйте методы объектно-ориентированного программирования. C++ сделает программирование удовольствием, если вы будете знать, как использовать его возможности - наследование, ограничения доступа и повторное использование кода.

При создании KDE или Qt проекта вы всегда наследуете объект Просмотра от `QWidget` непосредственно или через использование библиотечного элемента, унаследованного от `QWidget`. KAppWizard уже создал объект Просмотра, который является экземпляром класса <ваше_приложение>View, унаследованного от `QWidget`. Приложение создает его в методе `initView()`, где создается экземпляр объекта, который затем устанавливается как главный с помощью `KTMainWidget::setView()`.

Эта глава описывает, как использовать библиотеку элементов для создания главного объекта (объекта Просмотр) для KDE или Qt приложений, которые разрабатываются с помощью KDevelop. Мы просмотрим библиотеки и узнаем, какие типы элементов они предлагают.

### 4.1 Использование библиотечных элементов

Когда начинается разработка приложения, вы в первую очередь должны просмотреть уже существующий код, что сделает вашу жизнь гораздо легче. Например, необходимо изучить уже существующие элементы, которые могут быть использованы в качестве объектов Просмотра или как их часть, как непосредственно, так и путем наследования. Библиотеки KDE и Qt уже содержат набор элементов, которые могут быть использованы для этих целей. Вы имеете две возможности для их использования:

1. удалить объект Просмотра, включенный в шаблон, создать экземпляр библиотечного элемента и установить его как главный элемент;
2. изменить предка предложенного в шаблоне элемента на класс библиотечного элемента.

В любом случае, важно понимать, что если приложение на данный момент не линкуется с библиотекой, которая содержит новый элемент, линкование завершится с ошибкой. После того, как вы решили использовать определенный элемент, посмотрите, с какой библиотекой необходимо связаться. Потом откройте "Project"->"Options" из меню KDevelop, переключитесь на страницу "Linker Options" и посмотрите на то, какие библиотеки используются на текущий момент. Если среди них есть библиотека, в которой содержится ваш элемент, вы можете закрыть окно опций проекта без изменений и начать вносить необходимые изменения в ваш код. Если нет, и в опциях линкера есть возможность добавить необходимую библиотеку выбором соответствующего пункта, выберите его и нажмите "OK", чтобы закрыть окно опций проекта. В любом другом случае добавьте библиотеку в строку ввода внизу окна с опцией `-l`. Для библиотек, которые ваше приложение должно искать перед генерацией файлов Makefiles в скрипте `configure` на машине пользователя, добавьте соответствующий макрос для поиска в файл `configure.in`, расположенный в корневом каталоге проекта, и добавьте макрос для изменения строки. Имейте в виду, что вы должны запустить "Build"->"Autoconf" и "Build"->"Configure" для того, чтобы в файлы Makefile была записана правильная информация о макросе для вашей библиотеки.

Кроме того, если include-файлы добавленной библиотеки не попадают в текущий путь для поиска include-файлов (каталоги, заданные с помощью ключа `-I` в окне вывода информации о работе "Make"), вы должны добавить путь в диалоговом окне Project Options - страница "Compiler Options", с ключом `-I`, или соответствующий макрос automake в строке ввода "Additional Options".

#### Элементы Qt

На первой странице Qt online-документации вы найдете ссылку на картинки элементов "Widget Screenshots", где сможете посмотреть, как выглядят различные элементы Qt. Все они готовы к использованию и могут быть объединены вместе для создания сложных главных окон приложений или диалогов. Далее мы описываем некоторые из этих элементов, которые очень полезны при разработке приложений и элементов Просмотр, но имейте в виду, что библиотеки KDE иногда содержат другие элементы, выполняющие те же задачи; их мы обсудим в следующем разделе.

Перед вами несколько подсказок, для каких целей какие элементы Qt использовать:

1. если ваша область просмотра недостаточно велика, чтобы вместить все данные, необходимо обеспечить пользователю возможность прокрутки (скроллинга) с помощью полос прокрутки справа и внизу. Для этого Qt предоставляет класс `QScrollView`, у которого имеется пользовательская область с обеспечением прокрутки. Вы можете наследовать свой собственный элемент от `QScrollView` или использовать его экземпляр для организации просмотра в вашем приложении.
2. для создания прокручиваемой области самостоятельно наследуйте объект Просмотра от класса `QWidget` и добавьте к нему вертикальную и горизонтальную прокрутку `QScrollBar` (это сделано в KDE для элемента KHTMLView);
3. для текстовой обработки используйте `QMultiLineEdit`. Этот класс предоставляет полнофункциональный текстовый редактор, умеющий работать с буфером обмена и полосами прокрутки;
4. используйте `QTableView`, чтобы отобразить данные в табличной форме. `QTableView` управляется полосами прокрутки, поэтому он - хорошее решение для приложения типа электронных таблиц.
5. для одновременного отображения двух различных элементов или двух экземпляров элемента используйте `QSplitter`. Это позволит разделить область просмотра горизонтально или вертикально. Окно Netscape's Mail - хороший пример того, как это выглядит. Главное окно разделено по вертикали, а правая часть снова разделена по горизонтали.
6. `QListView` отображает информацию в виде дерева. Это полезно для представления дерева каталогов или другой иерархической информации, которую необходимо обрабатывать.

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

#### Элементы KDE

Библиотеки KDE созданы для облегчения разработки приложений K Desktop Environment, и поддерживают всю функциональность, реализованную в Qt. Чтобы определить, что нам доступно, посмотрим на дерево документации в KDevelop. Мы видим, что библиотеки KDE начинаются с `kdecore`, которая является основой для всех приложений KDE. Идущая следом `kdeui` предоставляет элементы пользовательского интерфейса. Здесь мы найдем несколько полезных вещей. Для создания приложений `kdeui` предлагает:

1. `KTabListBox`: список с несколькими столбцами, строки которого можно изменять с помощью drag'n drop.
2. `KTreeList`: унаследованный от `QTableView`, реализует дерево с возможностью показа/скрытия веток. Может быть использован вместо `QListView`. В KDE 2.0 этот класс реализован не будет.
3. `KEdit`: базовый класс для приложения KEdit, поставляемого вместе с KDE; может использоваться вместо `QMultiLineEdit`.
4. `KNewPanner`: Управляет двумя дочерними элементами как `QSplitter`. В KDE 2.0 этот класс реализован не будет.

Библиотека `khtmlw` предоставляет полнофункциональный интерпретатор HTML документов, готовый к использованию. Он поддерживает прокрутку, поэтому вы не должны о ней заботиться. Может быть полезен как интегрированное средство просмотра в HTML-редакторе; используется такими приложениями, как KFM, KDEHelp и KDevelop для показа HTML файлов.

### 4.2 Создание собственного элемента просмотра

Теперь, когда вы получили общее представление о предоставляемых возможностях, можно заметить, что для большинства задач уже существуют элементы, которые могут быть использованы самостоятельно или объединены с другими. KMail и сам KDevelop - хорошие примеры использования библиотечных элементов для отображения данных.

Для приложений, которые используют специфические форматы файлов или имеют дело с графикой, вы, вероятно, будете вынуждены создать свой собственный элемент просмотра для организации обработки данных. Это реализуется в нашем примере с помощью класса `KScribbleView`, уже имеющего все необходимое для области просмотра.

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

Повторим для полноты подлежащие переопределению методы:

a) События клавиатуры -- клавиши TAB и Shift-TAB :

изменяет фокус ввода с клавиатуры с текущего элемента на следующий элемент в порядке изменения фокусов. Фокус может быть установлен для элемента вызовом `setFocusPolicy ()`. Изменение фокуса обрабатывается следующими обработчиками событий: :

- `virtual void focusInEvent ( QFocusEvent * )`
- `virtual void focusOutEvent ( QFocusEvent * )`

b) другой ввод с клавиатуры:

- `virtual void keyPressEvent ( QKeyEvent * )`
- `virtual void keyReleaseEvent ( QKeyEvent * )`

c) перемещение мыши:

- `virtual void mouseMoveEvent ( QMouseEvent * )`
- `virtual void enterEvent ( QEvent * )`
- `virtual void leaveEvent ( QEvent * )`

d) нажатие кнопок мыши:

- `virtual void mousePressEvent ( QMouseEvent * )`
- `virtual void mouseReleaseEvent ( QMouseEvent * )`
- `virtual void mouseDoubleClickEvent ( QMouseEvent * )`

e) события окна, содержащего элемент:

- `virtual void moveEvent ( QMoveEvent * )`
- `virtual void resizeEvent ( QResizeEvent * )`
- `virtual void closeEvent ( QCloseEvent * )`

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

1. объявляйте ваши виртуальные методы как virtual в секции protected. Это позволит переиспользовать код при наследовании и обеспечит логическую целостность;
2. не включайте в текст программы, реализующей обработку событий, непосредственно (hard-code) ничего такого, что может конфигурироваться. Это в основном относится к событиям клавиатуры, которые реализуются через горячие клавиши и состоят в вызове функций. Данное замечание касается даже текстовой обработки! (Вообразите себе, что множество пользователей привыкли к своему любимому текстовому редактору. Если горячие клавиши конфигурируются, то они смогут использовать привычные для себя настройки);
3. передавайте сигналы, генерируемые при подсветке пунктов меню, главному элементу, чтобы обеспечить подсказки в строке статуса.

Next Previous Table of Contents