Next Previous Table of Contents

### 4. Application View Design

When developing an application with a graphical user interface, the main work takes place in providing a so-called "view" for the application. A view generally is a widget that displays the data of a document and provides methods to manipulate the document contents. This can be done by the user via the events he emits by the keyboard or the mouse; more complex operations are often processed by toolbars and menubars which interact with the view and the document. The statusbar then provides information about the document, view or application status. As an example, we look at how an editor is constructed and where we can find which part.

An editor generally is supposed to provide an interface to view and/or change the contents of a text document for the user. If you start KEdit, you see the visual interface as the following:

- The menubar: providing complex operations as well as opening, saving and closing files and exiting the application.
- The toolbar: offers icons which allow quicker access for most needed functions,
- The statusbar: displays the status of the cursor position by the current row and column,
- The view in the center of the window, displaying a document and offering a cursor connected to the keyboard and the mouse to operate on the data.

Now it's easy to understand, that a view is the most unique part of the application and the design of the view decides about the usability and acceptability of an application. This means that one of the first steps in development is to determine the purpose of the application and what kind of view design would match best to allow any user to work with the application with a minimum of work learning how to handle the user interface.

For some purposes like text editing and displaying HTML files, views are provided by the Qt and KDE libraries; we will discuss certain aspects of these high-level widgets in the next section. But for most applications new widgets have to be designed and implemented. It is that what makes a programmer also a designer and where his abilities on creativity are asked. Nevertheless, you should watch for intuitivity first. Remember that a lot of users won't accept an application that isn't

- graphically nice,
- offering a lot of features,
- easy to handle,
- fast to learn how to use it.

Needless to say that stability is a major design goal. Nobody can prevent bugs, but a minimum can be reached at least by clever design goals and wide use of object-oriented design. C++ makes programming a joy if you know how to exploit it's capabilities- inheritance, information hiding and reusablitity of already existing code.

When creating a KDE or Qt project, you always have to have a view that inherits `QWidget`, either by direct inheritance or because the library widget you want to use inherits `QWidget`. Therefore, the Application Wizard already constructed a view that is an instance of a class `<yourapp>View`, which inherits `QWidget` already. The application creates your view in the method `initView()`, where an instance is created and connected to the main widget as it's view with `KTMainWidget::setView()`.

This chapter therefore describes how to use library widgets for creating views of KDE or Qt applications that are generated with KDevelop, then we're looking at the libraries and what kind of views are already offered.

### 4.1 Using Library Views

When your application design has been set up, you first should look for already existing code that will make your life a lot easier. A part of this search is to look for a widget that can be used as a view or at least as a part of it; either directly or by inheritance. The KDE and Qt libraries already contain a set of widgets that can be used for this purpose. To use them, you have two options:

1. remove the new view class and create an instance of a library widget; then set this as the view,
2. change the inheritance of the provided view class to the class of the library widget to use.

In either way, it is important to know that if the application framework is currently not linked against the library that contains the widget, the linker will fail. After you decided to use a certain widget, look for the library to link to; then open "Project"->"Options" from the KDevelop menubar. Switch to the "Linker Options" page and look for the checkmarks indicating the libraries that are currently used. If the library of your view widget is already checked, you can leave the project options untouched and start doing the necessary changes due to your choice. If not, and the linker options offer to add the library by a check box, check it and press "OK" to leave the project options dialog again. In any other case, add the library in the edit line below with the `-l` option. For libraries that your application has to search for before preparing the Makefiles by the `configure` script on the end-user machine, add the according search macro to the `configure.in` file located at the root directory of your project and add the macro to the edit line. Mind that you have to run "Build"->"Autoconf and automake" and "Build"->"Configure" before the Makefiles contain the correct expansion for the library macro.

Also, if the include files for the library to add are not in the current include path (which can be seen by the `-I` options in the output window on "Make"), you have to add the path to the Project Options dialog -"Compiler Options" page with the `-I` option or the according automake macro at the edit line for "Additional Options".

#### Qt Views

Looking at the first page of the Qt online documentation, you will find a link to "Widget Screenshots" where you can have a look at how the widgets Qt contains look like. These are ready to use and can be combined together to form complex widgets to create application views or dialogs. In the following, we'll discuss some of these which are very usable for creating application views, but keep in mind that the KDE libraries sometimes contain other widgets for the same purpose; those will be reviewed in the next section.

Here are a set of hints for what purpose you could use which Qt component:

1. if your view area isn't big enough to display all your data, the user must be enabled to scroll over the document with bars on the left and bottom of the view. For this, Qt provides the class `QScrollView`, which offers a scrollable child area. As explained, you could inherit your own widget from `QScrollView` or use an instance to manage your document's view widget.
2. to create a ScrollView yourself, inherit the View widget from `QWidget` and add vertical and horizontal `QScrollBar`s. (this is done by KDE`s KHTMLView widget).
3. for text processing, use `QMultiLineEdit`. This class provides a complete text editor widget that is already capable to cut, copy and paste text and is managed by a scrollview.
4. use `QTableView` to display data that is arranged in a table. As `QTableView` is managed by scrollbars as well, it offers a good solution for table calculation applications.
5. to display two different widgets or two widget instances at the same time, use `QSplitter`. This allows to tile views by horizontal or vertical dividers. Netscape's Mail window is a good example how this would look like- the main view is separated by a splitter vertically, the right window then is divided again horizontally.
6. `QListView` displays information in a list and tree. This is useful for creating file trees or any other hierarchical information you want to interact with.

You see that Qt alone offers a whole set of widgets which are ready to use so you don't have to invent new solutions if these match your needs. The sideffect when using standard widgets is that users already know how to handle them and only have to concentrate on the displayed data.

#### KDE Views

The KDE libraries were invented to make designing applications for the K Desktop Environment easier and capable of more functionality than what Qt alone is offering. To see what's available, we have a look at the documentation tree in KDevelop. You see that the KDE libraries start with `kdecore`, which is a base for all KDE applications. Then,`kdeui` offers user interface elements. This is where we will find some useful things first. For creating new applications, the `kdeui` library offers:

1. `KTabListBox`: offers a multi-column list box where the user can change the rows with drag'n drop.
2. `KTreeList`: inherited from `QTableView`, offering a collapsible tree. This could be used instead of `QListView`. In KDE 2.0, this class will disappear.
3. `KEdit`: the base classes for the KEdit application offered with KDE. This could be used instead of `QMultiLineEdit`.
4. `KNewPanner`: manage two child widgets like `QSplitter`. In KDE 2.0, this class will disappear.

The `khtmlw` library on the other hand offers a complete HTML-interpreting widget that is ready to use. It is scrollable already, so you don't even have to take care for that. A possible use could be to integrate it as a preview widget for an HTML editor; used by applications such as KFM, KDEHelp and KDevelop to display HTML files.

### 4.2 Creating your own Views

Now that you have a general overview of what is already provided, you may notice that for a lot of purposes already existing widgets can be used or combined together. KMail is an example as well as KDevelop itself makes use of library view components to display data.

For applications that use a special file format or have to deal with graphics, you are probably forced to create your own view widget to allow data manipulation. This is realized in our sample by the class `KScribbleView`, already providing a base for a view area.

The inheritance from `QWidget` is necessary to overwrite the virtual methods to process user events, this is probably the most work besides providing popup menus for easier access of certain functions. Also it is likely that you have to implement a set of slots which can be accessed by toolbar buttons or menu bar commands to connect to as well as methods to manipulate variables such as e.g. a painter color.

For completeness, we will repeat the necessary methods:

a) Keyboard events --TAB and Shift-TAB keys:

changes the keyboard input focus from the current widget to the next widget in the focus order. The focus can be set to widgets by calling `setFocusPolicy ()` and process the following event handlers:

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

b) all other keyboard input:

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

c) mouse movements:

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

d) mouse button actions:

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

e) window events containing the widget:

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

When re-implementing these functions, you should watch certain issues to avoid implementation mistakes that will make it almost impossible to change the widget's behavior afterwards:

1. declare your virtual methods as virtual as well and keep the access to protected. This allows code-reuse by inheritance and is consistent.
2. don't hard-code any event-processing which should be made configurable. This counts most for keyboard events which should be realized with keyboard accelerator s if any function is called. This even counts for text processing ! (Imagine that a lot of users are familiar with their favorite editor's behavior. If this is configurable, they can use the behavior they like and are used to)
3. forward popup menu highlighting signals to the main widget to enable statusbar help

Next Previous Table of Contents