Página seguinte Página anterior Índice geral

### 4. Desenho de Vista de Aplicação

Quando se está a desenvolver uma aplicação com um interface gráfico de utilização, o trabalho principal é feito a disponibilizar a chamada "vista" para a aplicação. A vista geralmente é um widget que apresenta os dados de um documento e disponibiliza métodos para manipular o conteudo do documento. Isto pode ser feito pelo utilizador através de eventos que emite pelo teclado ou rato; operações mais complexas são muitas vezes processadas pelas barras de ferramentas e menus que interagem com a vista e o documento. A barra de estados apresenta informação sobre o estado do documento, vista ou aplicação. Como exemplo, olhamos para como um editor está construido e onde podemos encontrar cada parte.

Um editor é suposto geralmente disponibilizar um interface para o utilizador ver e/ou modificar o conteudo de um documento de texto. Se você iniciar o KEdit, vê o interface visual da seguinte forma:

- A barra de menu: disponibiliza operações complexas bem como abrir, gravar e fechar ficheiros e sair da aplicação.
- A barra de ferramentas: oferece icons que permitem um acesso rápido para as funções mais necessárias,
- A barra de estados: apresenta o estado da posição do cursor através da linha e coluna actuais,
- A vista no centro da janela, apresentando um documento e oferecendo um cursor conectado ao teclado e rato para trabalhar sobre os dados.

Agora é fácil compreender, que uma vista é uma parte única da aplicação e que o desenho da vista decide sobre a usabilidade e aceitação de uma aplicação. Isto significa que um dos primeiros passos no desenvolvimento é determinar o objectivo da aplicação e que tipo de desenho lhe iria mais de encontro para permitir a qualquer utilizador trabalhar com a aplicação com um mínimo de trabalho de aprendizagem de como utilizar o interface gráfico.

Para alguns objectivos como edição de texto e apresentação de ficheiros HTML, as vistas são disponibilizadas pelas bibliotecas Qt e KDE; iremos discutir alguns aspectos destes widgets de alto-nível na próxima secção. Mas para a maioria das aplicações novos widgets têm de ser desenhados e implementados. É isso que faz um programador e também um desenhador e onde as suas capacidades em criatividade são necessárias. De qualquer modo, deverá procurar a intuição primeiro. Lembre-se que imensos utilizadores não aceitarão uma aplicação que não seja

- bonita graficamente,
- oferece imensas funcionalidades,
- fácil de utilizar,
- rápida de aprender como utilizar.

Desnecessário dizer que a estabilidade é um dos objectivos principais. Ninguém pode impedir erros de código, mas um mínimo pode ser atingido pelo menos por objectivos de desenho inteligentes e a utilização de desenho orientado por objectos. C++ torna a programação um prazer se você souber como explorar as suas capacidades- hereditariedade, ocultação de informação e reutilização de código já existente.

Quando se cria um projecto KDE ou Qt, você tem sempre de ter uma vista que herda `QWidget`, quer por herança directa ou porque a biblioteca do widget que quer utilizar herda `QWidget`. Assim, o Assistente de Aplicação já constroi a vista que é uma instância da classe `<yourapp>View`, que já herda `QWidget`. A aplicação cria a sua vista no método `initView()`, onde uma instãncia é criada e conectada com o widget principal como sua vista com `KTMainWidget::setView()`.

Este capítulo descreve assim como utilizar bibliotecas de widgets para criar vistas de aplicações KDE ou Qt que são geradas com o KDevelop, depois iremos observar as bibliotecas e que tipos de vistas são já oferecidas.

### 4.1 Utilizar Bibliotecas de Vistas

Quando o desenho da sua aplicação estiver definido, você deverá primeiro procurar código já existente que fará a sua vida muito mais simples. Uma parte desta busca é a procura de um widget que possa ser utilizado como vista ou pelo menos parte dela; quer directamente ou por hereditariedade. As bibliotecas KDE e Qt já contêm um conjunto de widgets que podem ser utilizados para este propósito. Para os utilizar, você tem duas opções:

1. remover a nova classe de cista e criar uma instância de um widget de biblioteca; depois defini-lo como vista,
2. modificar a hereditariedade da classe de vista disponibilizada para a classe do widget de biblioteca a utilizar.

De qualquer uma das formas, é importante saber que se a estrutura de aplicação não está actualmente ligada a nenhuma biblioteca que contenha o widget, o linker irá falhar. Depois de se decidir a utilizar um certo widget, procure a biblioteca a linkar; depois abra "Projecto"->"Opções" na barra de menu do KDevelop. Vá para a página "Opções do Linker" e procure as caixas de selecção que indiquem as bibliotecas que estão correntemente a serem utilizadas. Se a biblioteca do seu widget de vista já estiver seleccionada, pode deixar as opções do projecto intocadas e começar a fazer as alterações necessárias devido à sua escolha. Caso contrário, a opção de linker permite adicionar a biblioteca através de uma caixa de selecção, active-a e prima "OK" para sair de novo do diálogo de opções do projecto. Em qualquer outro caso, adicione a biblioteca na linha de edição por baixo da opção `-l`. Para bibliotecas que a sua aplicação tem de procurar antes de preparar os ficheiros Makefiles através do script `configure` na máquina do utilizador final, adicione a seguinte macro de procura ao ficheiro `configure.in` localizado na raiz do directório do seu projecto e adicione a macro à linha de edição. Lembre-se que tem de correr "Construir"->"Autoconf e automake" e "Construir"->"Configurar" antes dos Makefiles conterem as expansões correctas para a macro de biblioteca.

Também, se os ficheiros inclued para a biblioteca a adicionar não estiverem no caminho actual de include (que pode ser visto pela opção `-I` na janela de output ao fazer "Make"), tem de adicionar o caminho no diálogo de Opções de Projecto -página "Opções de Compilador" com a opção `-I` ou a correspondente macro de automake na linha de edição para "Opções Adicionais".

#### 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`.
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`.

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

Página seguinte Página anterior Índice geral