Le Manuel de Programmation de KDevelop: Conception de Vue d'Application

Page suivante Page précédente Table des matières

### 4. Conception de Vue d'Application

Lorsque vous développez une application ayant une interface utilisateur graphique, la tâche principale est de fournir des "vues" à l'application. Une vue est généralement un widget qui affiche les données d'un document et fournit des méthodes pour manipuler le contenu du document. Cela peut être fait par l'utilisateur via des événements qu'il émet avec le clavier ou la souris ; les opérations plus complexes sont généralement traitées par les barres d'outils et les barres de menus qui interagissent avec la vue et le document. La barre d'état donne des informations sur le document, la vue ou l'état de l'application. À titre d'exemple, nous regarderons comment un éditeur est construit et où nous pouvons trouver tel et tel élément.

Un éditeur est généralement supposé fournir une interface à l'utilisateur lui permettant de visualiser et/ou modifier le contenu d'un document texte. Si vous lancez KEdit, vous voyez l'interface visuelle suivante :

- la barre de menus : fournit des opérations complexes comme l'ouverture, l'enregistrement et la fermeture de fichiers ainsi que l'arrêt de l'application
- la barre d'outils : fournit des icônes qui permettent d'accéder plus rapidement aux fonctions les plus utilisées
- la barre d'état : affiche l'état de la position du curseur avec la ligne et la colonne courante
- la vue au centre de la fenêtre : affiche un document et permet au curseur connecté au clavier et à la souris de travailler sur les données.

Il paraît donc évident que la vue est la partie la plus unique de l'application et que sa conception décide de l'utilisabilité et de l'acceptabilité de l'application. Cela signifie qu'une des premières étapes dans le développement est de déterminer le but de l'application et quel type de concept de vue correspondra le mieux pour permettre à n'importe quel utilisateur de travailler avec l'application en fournissant un minimum d'effort pour apprendre à dominer l'interface utilisateur.

Pour certains cas comme l'édition de texte ou l'affichage de fichiers HTML, des vues sont fournies par Qt et par les bibliothèques de KDE ; nous discuterons certains aspects de ces widgets de haut niveau dans la section suivante. Mais pour la plupart des applications, de nouveaux widgets doivent être conçus et implantés. C'est là que le programmeur devient un "designer" et qu'on lui demande d'être créatif. Mais, n'oubliez pas d'être intuitif. Souvenez-vous que beaucoup d'utilisateurs n'accepteront pas une application qui n'est pas :

- visuellement agréable
- pourvue de nombreuses fonctionnalités
- facile à manipuler
- d'utilisation rapidement assimilable.

Nul besoin d'ajouter que la stabilité est un objectif majeur. Personne ne peut éviter tous les bogues mais un minimum peut être atteint au moins grâce à une conception soignée et l'utilisation vaste de la conception orientée objet. Le C++ rend la programmation agréable si vous savez exploiter ses capacités - héritage, encapsulation et réutilisabilité du code existant.

Lorsque vous créez un projet KDE ou Qt, vous devez toujours avoir une vue qui hérite de `QWidget`, soit par héritage direct soit parce que le widget de la bibliothèque que vous voulez utiliser hérite de `QWidget`. C'est pourquoi, l'Assistant d'Application construit une vue qui est une instance de la classe `<yourapp>View` qui hérite déjà de `QWidget`. L'application crée votre vue dans la méthode `initView()` où une instance est créée et connectée au widget principal comme étant sa vue avec `KTMainWidget::setView()`.

Ce chapitre décrit donc comment utiliser les widgets des bibliothèques pour créer des vues pour les applications KDE ou Qt qui sont générées avec KDevelop ; ensuite, nous regarderons les bibliothèques et quels types de vues sont déjà fournis.

### 4.1 Utiliser les Vues des Bibliothèques

Quand la conception de votre application est achevée, vous devriez d'abord regarder le code existant qui vous rendra la vie plus facile. Une partie de ce travail est de chercher un widget qui peut être utilisé comme vue ou au moins comme un élément de celle-ci, soit directement soit par héritage. Les bibliothèques de KDE et Qt contiennent déjà un ensemble de widgets qui peuvent être utilisés pour cela. Pour les utiliser, vous avez deux options :

1. supprimer la nouvelle classe de vue et créer une instance du widget de la bibliothèque ; ensuite, définissez-le comme étant la vue
2. changer l'héritage de la classe de vue fournie en la classe du widget de la bibliothèque à utiliser.

De toute façon, il faut savoir que si l'application n'est actuellement pas liée avec la bibliothèque qui contient le widget, l'édition de lien échouera. Après avoir décidé d'utiliser un certain widget, regardez la bibliothèque à lier ; ensuite, ouvrez "Projet"->"Options" dans la barre de menus. Allez à la page "Édition de liens" et regardez les cases à cocher indiquant les bibliothèques actuellement utilisées. Si la bibliothèque de votre widget de vue est déjà cochée, vous pouvez laisser telles quelles les options du projet et commencer à effectuer les modifications nécessaires au gré de votre choix. Sinon, les options d'édition de lien vous permettent d'ajouter une bibliothèque grâce à une case à cocher, cochez-la et cliquez sur "OK" pour quitter la boîte de dialogue des options du projet. Dans les autres cas, ajoutez la bibliothèque dans la ligne d'édition en bas avec l'option `-l`. Pour les bibliothèques que votre application doit rechercher avant de préparer les Makefiles, sur la machine de l'utilisateur, avec le script `configure` , ajoutez la macro de recherche correspondante dans le fichier `configure.in` situé dans le dossier de base de votre projet et ajoutez la macro à la ligne d'édition. Notez que vous devez exécuter "Construire"->"Autoconf et automake" et "Construire->Configurer" avant que les Makefiles ne contiennent le contenu correct de la macro de la bibliothèque.

Également, si les fichiers d'include de la bibliothèque ne sont pas dans les chemins d'include actuels (que l'on peut voir avec l'option `-I` dans la fenêtres des messages de "Make"), vous devez ajouter le chemin dans la boîte de dialogue des Options du Projet, à la page "Options de compilation", avec l'option `-I` ou la macro automake correspondante dans la ligne d'édition des "Options supplémentaires".

#### Vues Qt

En regardant la première page de la documentation en ligne de Qt, vous trouverez un lien vers des captures d'écran de widgets (NdT : "Widget Screenshots") où vous pourrez voir à quoi ressemblent les widgets de Qt. Ils sont prêts à l'emploi et peuvent être combinés ensemble pour former des widgets complexes afin de créer des vues ou des boîtes de dialogue d'applications. Dans la suite, nous en présenterons certains qui sont très utiles pour créer des vues d'applications mais gardez à l'esprit que les bibliothèques de KDE contiennent parfois d'autres widgets ayant le même but ; nous les verrons dans la prochaine section.

Voici un ensemble de conseils sur l'utilisation des composants de Qt :

1. si votre zone de vue n'est pas assez grande pour afficher toutes les données, l'utilisateur doit pouvoir faire défiler le document grâce à des barres à droite et en bas de la vue. Pour cela, Qt fournit la classe `QScrollView` qui donne une zone fille que l'on peut faire défiler. Comme expliqué, vous pouvez faire hériter votre widget de `QScrollView` ou en utiliser une instance pour gérer le widget de vue de votre document ;
2. pour créer une ScrollView vous-même, dérivez le widget de View de `QWidget` et ajoutez des `QScrollBar`s verticale et horizontale (c'est ce que fait le widget KHTMLView de KDE) ;
3. pour du traitement de texte, utilisez `QMultiLineEdit`. Cette classe fournit un widget d'édition de texte complet qui est déjà capable de couper, copier et coller du texte et est géré par une barre de défilement ;
4. utilisez `QTableView` pour afficher des données qui sont organisées en table. Comme `QTableView` est gérée par des barres de défilement, c'est une bonne solution pour des applications de calcul sur des tables ;
5. pour afficher deux widgets différents ou deux instances du widget en même temps, utilisez `QSplitter`. Cela vous permet de séparer les vues en divisons horizontales ou verticales. La fenêtre de Mail de Netscape est un bon exemple de ce à quoi cela peut ressembler - la vue principale est divisée par un séparateur vertical, la fenêtre de droite est ensuite à nouveau divisée horizontalement ;
6. `QListView` affiche des informations dans une liste et un arbre. C'est utile pour créer des arborescences de fichiers ou toute information organisée hiérarchiquement avec laquelle vous voulez interagir.

Vous voyez que Qt, seul, offre un large éventail de widgets qui sont prêts à l'emploi donc vous n'avez pas besoin d'inventer de nouvelles solutions si ceux-ci vous conviennent. L'avantage d'utiliser des widgets standards est que les utilisateurs savent déjà comment les manipuler et n'ont plus qu'à se concentrer sur les données affichées.

#### Vues KDE

Les bibliothèques de KDE ont été inventées pour rendre plus simple la conception d'applications pour l'Environnement de Bureau KDE et apporter plus de fonctionnalités que celles offertes par Qt seul. Pour voir ce qui est disponible, nous allons regarder l'arbre de documentation dans KDevelop. Vous voyez que les bibliothèques de KDE commencent avec `kdecore` qui est la base de toutes les applications KDE. Ensuite, `kdeui` apporte des éléments d'interface utilisateur. C'est là que vous trouverez des choses utiles. Pour créer de nouvelles applications, la bibliothèque `kdeui` contient :

1. `KTabListBox` : une zone de liste multi-colonnes où l'utilisateur peut changer les lignes par glisser-déposer (NdT : drag'n drop) ;
2. `KTreeList` : hérite de `QTableView` et fournit un arbre développable/réductible (NdT : collapsible tree). Cela peut être utilisé à la place de `QListView`. Dans KDE 2.0, cette classe disparaîtra ;
3. `KEdit` : les classes de base de l'application KEdit qui fait partie de KDE. Cela peut être utilisé à la place de `QMultiLineEdit` ;
4. `KNewPanner` : gère deux widgets fils comme `QSplitter`. Dans KDE 2.0, cette classe disparaîtra ;

Par ailleurs, la bibliothèque `khtmlw` fournit un widget complet d'interprétation HTML prêt à l'emploi. On peut déjà le faire défiler donc vous n'avez pas besoin de vous en soucier. Une utilisation possible est de l'intégrer comme widget de prévisualisation pour un éditeur HTML ; il est également utilisé par des applications comme KFM, KDEHelp et KDevelop pour afficher des fichiers HTML.

### 4.2 Créer vos propres Vues

Maintenant que vous avez une vision globale de ce qui est déjà fourni, vous pourrez remarquer que pour beaucoup de types d'utilisation, des widgets existent déjà et sont prêts à l'emploi ou peuvent être combinés ensemble. KMail, ainsi que KDevelop lui-même utilisent des composants de bibliothèques de vues pour afficher leurs données.

Pour les applications qui utilisent un format de fichier spécial ou qui doivent utiliser des fonctions graphiques, vous serez probablement forcé de créer votre propre widget de vue pour manipuler les données. Cela est réalisé dans notre exemple par la classe `KScribbleView` qui fournit déjà une zone de vue de base.

Hériter de `QWidget` est nécessaire pour surcharger les méthodes virtuelles afin de traiter les événements utilisateur, c'est probablement le travail le plus long, au-delà de fournir les menus popups pour accéder facilement à certaines fonctions. Il paraît également judicieux d'implanter un ensemble de slots auxquels on peut accéder grâce aux boutons de la barre d'outils ou aux commandes de la barre de menus pour s'y connecter, ainsi que des méthodes pour manipuler des variables comme, par exemple, une couleur de dessin.

Afin d'être complets, nous allons répéter les méthodes nécessaires :

a) Événements Clavier -- les touches TAB et Shift-TAB :

changent le focus d'entrée du clavier du widget courant vers le widget suivant dans l'ordre du focus. Le focus peut être donné aux widgets en appelant `setFocusPolicy ()` et en traitant les événements suivants :

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

b) toute autre saisie au clavier :

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

c) mouvements de la souris :

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

d) actions des boutons de la souris :

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

e) événements de la fenêtre contenant le widget :

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

En ré-implantant ces fonctions, vous devrez prendre garde à certains points pour éviter des erreurs d'implantation qui rendront impossible une modification ultérieure du comportement du widget :

1. déclarez vos méthodes virtuelles comme virtual et conservez l'accès "protégé" (NdT : protected). Cela permet de réutiliser le widget par héritage et conserve une certaine homogénéité ;
2. ne codez pas en dur un traitement d'événement qui devrait être configurable. Cela est d'autant plus vrai pour les événements du clavier qui pourraient être réalisés avec des raccourcis clavier si une fonction est appelée. Cela est même valable pour les traitements de texte ! (pensez que beaucoup d'utilisateurs sont habitués au comportement de leur éditeur favori. Si cela est configurable, ils pourront utiliser le comportement auquel ils sont habitués) ;
3. transmettez le "signal" de surbrillance (NdT : highlighting) des menus popups au widget principal pour activer l'aide dans la barre d'état.

Page suivante Page précédente Table des matières