télécom sudparis — 1ère année · 2014. 6. 4. · l’utilisateur peut, en général,...

29
Développement d’applications graphiques Département Informatique Télécom SudParis — 1ère année TÉLÉCOM SudParis — INF Mars 2014

Upload: others

Post on 24-Mar-2021

1 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Télécom SudParis — 1ère année · 2014. 6. 4. · L’utilisateur peut, en général, interagir à tout moment avec l’application par le biais de la souris Le programme ne

Développement d’applicationsgraphiques

Département Informatique

Télécom SudParis — 1ère année

TÉLÉCOM SudParis — INF Mars 2014

Page 2: Télécom SudParis — 1ère année · 2014. 6. 4. · L’utilisateur peut, en général, interagir à tout moment avec l’application par le biais de la souris Le programme ne

Développement d’applications graphiques

Contents

Développement d’applications graphiquesDépartement Informatique, , TÉLÉCOM SudParis — INF, Télécom SudParis — 1èreannéeMars 2014 1

Plan 3

1 Généralités sur la conception d’applications graphiques 41.1 Application en mode terminal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51.2 Application graphique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61.3 Structuration client-serveur avec XWindow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71.4 Programmation événementielle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81.5 Structure type d’une application graphique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91.6 Les widgets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101.7 Bibliothèques graphiques de haut niveau . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

2 Introduction à Gtk 122.1 Aperçu de la hiérarchie de widgets Gtk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132.2 Un exemple simple d’interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142.3 Programme Gtk en C pour cette interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152.4 Compilation d’une application Gtk en C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162.5 Concepteur d’interface Glade . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172.6 Description XML de l’exemple d’interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182.7 Utilisation en C d’une description XML d’interface . . . . . . . . . . . . . . . . . . . . . . . . . 19

3 Version graphique de l’application exemple 203.1 Organisation générale de l’application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213.2 Adaptation à réaliser pour gtk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223.3 Structure générale de la version graphique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233.4 Éléments de l’interface graphique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243.5 Interaction pour l’ajout d’un ouvrage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253.6 Interaction graphique pour l’ajout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263.7 Affichage de la boîte de dialogue Ajout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273.8 Validation des informations saisies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283.9 Récupération des informations saisies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

TÉLÉCOM SudParis — INF — Département Informatique — Mars 2014 — Télécom SudParis — 1ère année 2

Page 3: Télécom SudParis — 1ère année · 2014. 6. 4. · L’utilisateur peut, en général, interagir à tout moment avec l’application par le biais de la souris Le programme ne

Développement d’applications graphiques

# 2

'

&

$

%

Plan

1 Généralités sur la conception d’applications graphiques . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 Introduction à Gtk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113 Application exemple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

L’objectif de cette présentation est de donner un aperçu de l’organisation du développement d’une ap-plication graphique et quelques indications pratiques pour faciliter un tel développement en s’appuyant surla bibliothèque graphique Gtk et sur l’outil Glade.

Il ne s’agit cependant que d’une introduction et l’étude des documentations et des tutoriels correspondantsest bien entendu indispensable pour mener à bien une réalisation.

TÉLÉCOM SudParis — INF — Département Informatique — Mars 2014 — Télécom SudParis — 1ère année 3

Page 4: Télécom SudParis — 1ère année · 2014. 6. 4. · L’utilisateur peut, en général, interagir à tout moment avec l’application par le biais de la souris Le programme ne

Développement d’applications graphiques

# 3

'

&

$

%

1 Généralités sur la conception d’applications graphiques

1.1 Application en mode terminal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41.2 Application graphique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51.3 Structuration client-serveur avec XWindow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61.4 Programmation événementielle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71.5 Structure type d’une application graphique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81.6 Les widgets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91.7 Bibliothèques graphiques de haut niveau . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .10

L’objectif d’une application est la production potentielle d’un ensemble de résultats à partir d’un ensemblede données. Toute application comporte donc sous une forme ou une autre une partie traitement chargée ducalcul de résultats pertinents à partir des données disponibles, et une partie interface utilisateur dédiée à larécupération des informations à traiter par l’application et à la présentation des résultats attendus.

Une application graphique permet une interaction de l’utilisateur avec l’application beaucoup plus richeet confortable qu’une application en mode terminal.

D’une façon générale, les interfaces graphiques reposent sur deux notions clés : les widgets, ou composantsgraphiques de l’interface, et les événements, générés à la suite d’actions de l’utilisateur.

Pour une application graphique, le travail de conception, de développement, et de test de l’interfaceutilisateur peut être très conséquent, alors que les mécanismes mis en jeu sont souvent les mêmes d’uneapplication graphique à l’autre. Aussi, des briques de base ont-elles été développées une fois pour toutes etmises à disposition des programmeurs sous forme d’environnements et de bibliothèques graphiques.

TÉLÉCOM SudParis — INF — Département Informatique — Mars 2014 — Télécom SudParis — 1ère année 4

Page 5: Télécom SudParis — 1ère année · 2014. 6. 4. · L’utilisateur peut, en général, interagir à tout moment avec l’application par le biais de la souris Le programme ne

Développement d’applications graphiques 1 Généralités sur la conception d’applications graphiques

# 4

'

&

$

%

1.1 Application en mode terminal

� Exécution dans le cadre d’une console

� Déroulement de l’interaction selon une séquence prédéterminée� Le programme “contrôle les opérations”,� L’utilisateur n’est sollicité que pour saisir des informations au moment voulu

⇒ faible interactivité

� Interface utilisateur en mode texte (CLI)� Possibilités d’interactions très limitéesI actions sur les touches du clavier

� Saisie d’informations exclusivement textuellesI données numériques, textes, noms de fichiers...

� Possibilités d’affichage très limitéesI caractères alphanumériques, séquences d’échappement

L’interface utilisateur est constituée de l’ensemble des moyens mis à disposition de l’utilisateur pourinteragir avec l’application afin d’utiliser les fonctionnalités proposées par celle-ci. Elle permet à l’utilisateur,lors de l’exécution de l’application, de choisir les résultats qu’il souhaite produire parmi toutes les possibilitésoffertes par l’application, de préciser les données à soumettre aux traitements sélectionnés, et de prendreconnaissance des résultats produits par l’application. Son ergonomie détermine le confort d’utilisation del’application.

L’interactivité d’une application caractérise la fréquence à laquelle l’utilisateur peut intervenir sur ledéroulement de cette application.

Dans le cas d’une application en mode terminal, l’utilisateur n’a “la main” qu’à des instants prédéter-minés, généralement avant d’engager les traitements (de façon à choisir ceux-ci et fixer les données à traiter).L’utilisateur n’interagit avec l’application qu’à travers des saisies clavier ; on parle de Command-LineInterface (CLI). Ces saisies nécessitent en général beaucoup de soin pour garantir un comportement fiable del’application et en assurer une utilisation confortable (confirmations utilisateur, validation des saisies avantutilisation...) ; il peut être nécessaire de leur consacrer un temps important de conception, de développement,et de test.

En dehors des saisies sollicitées par le programme, l’utilisateur ne peut intervenir de manière asynchronesur le déroulement de l’exécution d’une application en mode terminal que pour l’arrêter prématurément(combinaison de touches Ctrl-C) ou pour la suspendre (Ctrl-Z).

TÉLÉCOM SudParis — INF — Département Informatique — Mars 2014 — Télécom SudParis — 1ère année 5

Page 6: Télécom SudParis — 1ère année · 2014. 6. 4. · L’utilisateur peut, en général, interagir à tout moment avec l’application par le biais de la souris Le programme ne

Développement d’applications graphiques 1 Généralités sur la conception d’applications graphiques

# 5

'

&

$

%

1.2 Application graphique

� Exécution dans le cadre d’une fenêtre graphique� Déroulement de l’exécution soumis aux interventions de l’utilisateur

� L’utilisateur peut, en général, interagir à tout moment avec l’application par lebiais de la souris

� Le programme ne fait que réagir aux actions de l’utilisateur� Possibilités d’affichage très riches

� images, courbes, couleurs, épaisseur des traits, fonte des caractères� Interface utilisateur graphique (GUI)

� constituée d’éléments...I de présentation d’information : fenêtre, ascenseurs, imageI de saisie d’information : bouton, zone de saisieI mixtes (présentation/saisie) : liste déroulante (menu)

� organisée hiérarchiquementI racine de l’arborescence : fenêtre principaleI arborescence de composants graphiques

Grâce à une interface graphique, l’utilisateur peut communiquer ses ordres non plus seulement par leclavier, mais également en agissant, par l’intermédiaire de la souris, sur les différents composants de l’interfacegraphique.

L’application est a priori conçue pour être beaucoup plus interactive qu’une application en mode terminal.Elle permet en général à l’utilisateur d’intervenir à tout moment pour influer sur le déroulement de l’exécution: il peut, par exemple, cliquer où il veut quand il veut (avec ou sans effet cependant, certaines actions pouvantéventuellement être temporairement inhibées dans certaines circonstances). Le programme réagit aux actionsde l’utilisateur sur l’interface selon ce que le programmeur de l’application a prévu.

Toute application graphique s’exécute dans le cadre d’une (ou plusieurs) fenêtre(s), et présente àl’utilisateur une interface graphique ou GUI. L’acronyme GUI signifie Graphical User Interface.

L’interface est constituée de composants graphiques élémentaires appelés widgets, correspondant à deszones rectangulaires affichables et auxquelles sont attachées des sémantiques d’interaction : affichage, saisieclavier, sélection par un clic souris, etc.

Widget est l’acronyme de Windows, Icons, Dialog box, Graphics Extensions, Track ball, souvent déclinésous la forme WInDows gadGET.

Les caractéristiques d’une fenêtre sont liées à sa géométrie (taille, position à l’écran), sa bordure (épais-seur, couleur ou motif), son fond (couleur, motif ou transparence) ou encore la forme attribuée au curseurquand il est positionné dans la fenêtre.

Le programme peut associer des effets différents au clic, au double-clic, à l’action sur les différentsboutons de la souris, et prendre en compte le positionnement (coordonnées) du curseur dans la fenêtre ouses déplacements.

Le contenu (information/présentation) de l’affichage évolue en fonction des interactions de l’utilisateuravec l’interface graphique : mise à jour de certaines zones d’affichage, affichage d’informations complémen-taires...

Le concepteur de l’application devra définir les objets graphiques (menus, composants...) que contiendrala fenêtre principale de l’application et leur organisation selon une arborescence de widgets dont la racine estla fenêtre principale, les nœuds internes des conteneurs et les feuilles des widgets graphiques.

TÉLÉCOM SudParis — INF — Département Informatique — Mars 2014 — Télécom SudParis — 1ère année 6

Page 7: Télécom SudParis — 1ère année · 2014. 6. 4. · L’utilisateur peut, en général, interagir à tout moment avec l’application par le biais de la souris Le programme ne

Développement d’applications graphiques 1 Généralités sur la conception d’applications graphiques

# 6

'

&

$

%

1.3 Structuration client-serveur avec XWindow

� Le serveur graphique (serveur X )� s’exécute sur la machine de l’utilisateur (un seul serveur par machine)� attend les demandes de connexion d’applications clientes� reçoit et traite les requêtes des différentes applications clientes� gère l’affichage (tracés, texte) en s’appuyant sur des structures de données

(contextes graphiques) stockant les paramètres des actions graphiques (police,couleur, épaisseur de trait, motif de remplissage de zone)

� intercepte les actions de l’utilisateur (clavier, souris) et transmet les informationscorrespondantes aux applications concernées

� L’application cliente� s’exécute n’importe où, i.e. localement ou sur une machine distante� se connecte au serveur qui s’exécute sur la machine à laquelle est attachée la

console de l’utilisateur et s’enregistre pour être avertie de certaines actions� émet des requêtes, par exemple d’affichage, auprès du serveur� reçoit du serveur des informations sur les actions utilisateur auxquelles elle a

souscrit

Le fonctionnement d’une application dans un environnement graphique comme XWindow repose sur uneséparation des responsabilités entre l’application, qui exécute les traitements, et le serveur qui gère l’interfaceutilisateur. Le comportement du serveur a été écrit une fois pour toutes. Les développeurs d’applicationspeuvent donc se concentrer exclusivement sur la description des traitements propres à l’application.

La philosophie de XWindow repose sur la notion de ressources, qui doivent être chargées en mémoire parle serveur X ou créées pour pouvoir être utilisées. Celles-ci peuvent être des polices, des palettes (colormap),des contextes graphiques, des fenêtres, des matrices de pixels (pixmaps), etc.

XWindow est livré avec une bibliothèque de bas niveau de requêtes élémentaires au serveur X, la Xlib,interface de programmation du protocole X, dont la programmation est très technique (gestion explicite dudialogue de l’application avec le serveur X, utilisation du contexte graphique courant...).

Le serveur X s’exécute sur l’unité centrale directement raccordée à la console et gère en mémoire vive unensemble de ressources nécessaires à son travail d’affichage (palettes de couleurs, fontes, etc). Il surveille parailleurs les actions de l’utilisateur sur les différents éléments de l’interface utilisateur (fenêtres, etc) pour lestransmettre aux applications concernées.

Ces actions sont les saisies clavier (appui et relâchement de touches du clavier), les mouvements dela souris, les actions sur ses boutons (appui, relâchement) lorsque le curseur est positionné dans certainséléments de l’interface.

En fait, pour être notifiée de certaines actions de l’utilisateur par le serveur, une application doit aupar-avant s’enregistrer auprès du serveur pour les actions dont elle souhaite être alertée.

Quelques documents pour en savoir plus sur XWindow :Concepts X11Cours X11 (http://www.urec.cnrs.fr/IMG/ps/GERET-93.01-Cours.X11.ps)Quelques documents pour en savoir plus sur les internes de X et sur la Xlib :xwindow (http://www.u-picardie.fr/~ferment/xwindow/index.htm)motif (http://buffa.developpez.com/xwindow/)

TÉLÉCOM SudParis — INF — Département Informatique — Mars 2014 — Télécom SudParis — 1ère année 7

Page 8: Télécom SudParis — 1ère année · 2014. 6. 4. · L’utilisateur peut, en général, interagir à tout moment avec l’application par le biais de la souris Le programme ne

Développement d’applications graphiques 1 Généralités sur la conception d’applications graphiques

# 7

'

&

$

%

1.4 Programmation événementielle

� L’application est en permanence notifiée par le serveur graphique des actions del’utilisateur sur l’interface

� L’utilisateur "pilote" le programme, qui ne fait que réagir aux sollicitations del’utilisateur... à condition que ces réactions aient été prévues par le programmeur

� En réponse à une action de l’utilisateur, le serveur X construit une structureévénement du type ButtonPress, KeyPress, EnterNotify...

� Un événement contient toutes les informations concernant l’action associée :composant concerné, éléments de contexte

� Les infos associées à un événement dépendent de celui-ci� clic souris : coordonnées du point de clic� frappe d’un caractère : code du caractère frappé� événement lié à une fenêtre : redimensionnement, iconification

Dans un environnement graphique comme XWindow, le serveur graphique détecte en permanence lesactions utilisateur et construit les événements correspondant à ces actions. Le serveur transmet, à chaqueapplication cliente qui s’est enregistrée pour être notifiée, les événements correspondants sous forme d’unefile de messages.

L’application doit donc s’inscrire auprès du serveur pour recevoir les différents événements d’intérêt etdisposer de fonctions décrivant la manière de les traiter, appelées fonctions de rappel (callbacks).

Le concepteur de l’application définit les différentes actions que pourra effectuer l’utilisateur dans lafenêtre de l’application (cliquer sur tel bouton, sur tel item d’un menu...), et décrit les traitements corre-spondant aux réactions de l’application à chacune des actions prévues. Le programmeur de l’applicationdoit bien entendu décrire précisément ces réactions dans les fonctions de rappel.

Attention, le programmeur doit identifier a priori toutes les actions de l’utilisateur qu’il veut traiter ; ildoit décrire le traitement associé, mais sans savoir à quel moment l’action sera déclenchée... et la callbackcorrespondante exécutée. En effet, après une phase d’initialisation, une application graphique exécute uneboucle de surveillance des événements utilisateur auxquels elle est capable de répondre. Si l’application doitpasser successivement par un ensemble d’états à la suite des actions de l’utilisateur, comme par exemple poursimuler le déroulement d’une partie d’un jeu quelconque, il peut être nécessaire qu’une callback invoquéepuisse déterminer l’état courant afin de faire progresser l’application de façon pertinente vers un nouvel étatet préparer l’interface graphique pour l’interaction utilisateur suivante. Dans ce cas, l’état courant doit êtrereflété dans des variables rendues accessibles aux callbacks (soit par l’intermédiaire de variables globales, soitpar passage de paramètre).

TÉLÉCOM SudParis — INF — Département Informatique — Mars 2014 — Télécom SudParis — 1ère année 8

Page 9: Télécom SudParis — 1ère année · 2014. 6. 4. · L’utilisateur peut, en général, interagir à tout moment avec l’application par le biais de la souris Le programme ne

Développement d’applications graphiques 1 Généralités sur la conception d’applications graphiques

# 8

'

&

$

%

1.5 Structure type d’une application graphique

� Initialisation de l’usage de la bibliothèque graphique� Connexion au serveur X� Définition de ressources : palettes de couleurs, etc

� Mise en place des éléments de l’interface graphique� Création en mémoire vive d’une arborescence de widgets

� Association d’actions aux événements pertinents sur certains éléments� Connexion des paires widget/événement à des callbacks

� Affichage de l’interface� Mapping à l’écran de l’arborescence créée en mémoire vive

� Boucle de gestion des événements� Récupération du prochain événement� Traitement de l’événement récupéré

Une application graphique met en place un ensemble de widgets constituant l’interface utilisateur, puisréagit aux événements déclenchés par l’utilisateur, en exécutant les callbacks associées qui exploitent lesinformations correspondantes et provoquent éventuellement des mises à jour appropriées de certains élémentsde l’interface. Le programmeur doit donc choisir les widgets constituant l’interface et définir leur organisation,ainsi que les réactions de l’application aux actions de l’utilisateur sur ces widgets.

L’écriture du dialogue entre une application et un serveur graphique respectant un protocole tel quele protocole X serait fastidieuse. Heureusement, les bibliothèques graphiques proposent des primitives quiencapsulent un tel dialogue, ainsi que des composants graphiques de base prédéfinis permettant de construireplus confortablement des interfaces graphiques.

L’utilisation d’une bibliothèque s’appuie sur une API (Application Programming Interface) qui décritun ensemble de types prédéfinis et des fonctions pour manipuler les objets correspondants.

La programmation d’une application graphique repose sur l’utilisation d’une bibliothèque qui fournit uneAPI pour la gestion des widgets et des événements, ainsi que pour celle des ressources du serveur nécessairesà l’application.

Lorsqu’une application veut créer une fenêtre, elle adresse une requête au serveur X qui crée une réprésen-tation interne de la fenêtre en mémoire vive, en lui associant un identifiant et une pixmap (matrice de pixels).

Pour être visible, un widget doit être “mappé” à l’écran par le biais d’une requête d’affichage au serveurgraphique et ne devient visible que lorsque son parent est lui-même “mappé”. La fenêtre de plus haut niveaun’a pas de parent et devient visible dès qu’elle est “mappée”.

Le mapping à l’écran d’une fenêtre consiste pour le serveur X à recopier en mémoire graphique de l’écranla pixmap associée à la réprésentation logique interne de la fenêtre, ce qui la rend visible sur l’écran.

Pour construire une interface graphique aisément, le programmeur doit avoir une bonne connaissance desclasses de widgets disponibles dans la bibliothèque qu’il utilise, de façon à effectuer des choix pertinents. Ildoit en général travailler constamment avec la documentation de la bibliothèque.

TÉLÉCOM SudParis — INF — Département Informatique — Mars 2014 — Télécom SudParis — 1ère année 9

Page 10: Télécom SudParis — 1ère année · 2014. 6. 4. · L’utilisateur peut, en général, interagir à tout moment avec l’application par le biais de la souris Le programme ne

Développement d’applications graphiques 1 Généralités sur la conception d’applications graphiques

# 9

'

&

$

%

1.6 Les widgets

� widget = aspect graphique + comportement� Ils possédent des attributs et méthodes par défaut, mais modifiables� Ils sont définis et organisés selon une hiérarchie de classes fournie par l’API� Ils autorisent, par héritage, la définition de ses propres widgets utilisateur,

dérivés de classes prédéfinies� A chaque widget sont associés des événements auxquels l’application peut réagir

� Un événement se traduit par un message du serveur X vers l’application poursignaler une interaction utilisateur

� Il faut associer une fonction de rappel (callback) à un tel événement (paramètres: pointeurs sur le widget concerné et sur une donnée utilisateur)

� La structure logique d’une interface graphique est une arborescence comportant� des nœuds internes qui sont des widgets conteneursI avec pour un conteneur ayant plusieurs widgets enfants, la possibilité de

spécifier une disposition des enfants (tailles et positions relatives)� des nœuds feuilles qui sont de simples widgets

Les widgets, éléments de base qui composent une interface graphique (bouton, ascenseur...), correspondenten général à des régions de l’écran et sont généralement implémentés sous forme d’objets dont les types(ou classes) sont organisés en une hiérarchie d’héritage, ce qui permet de factoriser le code décrivant lesfonctionnalités de base de ces objets.

Il ne faut pas confondre d’une part la hiérarchie des classes de widgets construite lors de la définitiond’une bibliothèque graphique, et d’autre part, quand on considère une application particulière, la structurearborescente que celle-ci établit entre les widgets qui composent son interface graphique. Les nœuds internesde cette arborescence sont nécessairement des widgets conteneurs, qui permettent d’organiser la dispositionrelative de leurs widgets enfants dans la zone d’écran qui leur correspond dans l’interface graphique del’application, et selon leur type (alignement horizontal ou vertical des widgets enfants, par exemple).

Dans la conduite du dialogue avec l’utilisateur, trois notions clés interviennent :- la sensibilité : le widget répond ou non à une saisie (il apparaît normalement ou grisé),- le focus : le widget est la cible exclusive des saisies clavier quand il a le focus,- la capture (ou grab) du pointeur souris et du clavier : le widget ayant la capture devient un passage obligé,le reste de l’application étant figé (on parle de dialogue modal).

Au niveau programmation, les widgets, comme la plupart des ressources graphiques, sont manipulés àtravers des pointeurs qui sont souvent des variables globales, de façon à être accessibles sans passage deparamètre.

Les bibliothèques graphiques proposent en général un ensemble de widgets prédéfinis et prêts à l’emploidont le programmeur n’a plus qu’à fixer les caractéristiques pour composer son interface graphique.

En dehors de la fenêtre principale de l’application, racine de l’arborescence logique de l’interfacegraphique, chaque widget a un widget parent qui joue le rôle de conteneur et assure, lorsqu’il a plusieurswidgets enfants, leur positionnement relatif.

TÉLÉCOM SudParis — INF — Département Informatique — Mars 2014 — Télécom SudParis — 1ère année 10

Page 11: Télécom SudParis — 1ère année · 2014. 6. 4. · L’utilisateur peut, en général, interagir à tout moment avec l’application par le biais de la souris Le programme ne

Développement d’applications graphiques 1 Généralités sur la conception d’applications graphiques

# 10

'

&

$

%

1.7 Bibliothèques graphiques de haut niveau

� gdk� surcouche d’abstraction et de portabilité de la Xlib qui masque sa complexité

� Gtk (Gimp tool kit)� utilisée par gnome (environnement graphique de bureau Open Source)� boîte à outils constituée de bibliothèques indépendantes : Glib, Pango, ATK...� Gtk utilise plutôt gdk que directement la Xlib => Gtk disponible sous windows

� Qt� bibliothèque C++� utilisée par KDE (autre environnement graphique de bureau Open Source)

� Tk� bibliothèque graphique de widgets pour l’écriture de scripts Tcl/Tk avec GUI� surcouche de Xlib

� SDL� bibliothèque de programmation multimédia portable

Impossible de connaître une API par cœur => utiliser la documentation

Les primitives de la Xlib sont relativement basiques (tracé de ligne, récupération de caractères au clavier),mais permettent cependant de produire tous les effets utiles, au prix de combinaisons le plus souvent com-plexes.

Pour simplifier la programmation, on utilise plutôt des API de plus haut niveau, basées sur la Xlib, commela boîte à outils XToolkit, par exemple, qui comporte des structures de base permettant la construction dewidgets, et les éléments nécessaires pour implémenter des menus, des boîtes de dialogue, des barres dedéfilement, etc.

Le système XWindow est traditionnellement distribué avec la bibliothèque de widgets Athena (Xaw)fournie par le MIT.

Les bibliothèques graphiques les plus utilisées sur les systèmes GNU-Linux sont gdk, Gtk, Qt et Tk.gdk est le kit de dessin de l’application gimp (GNU image manipulation program, équivalent libre de Pho-

toshop), et peut être considéré comme une surcouche de la Xlib pour la rendre portable (il existe un portagesous Windows). Lorsque l’on programme avec gdk, la Xlib est néanmoins utilisable pour des manipulationsde plus bas niveau, en incluant gdk/gdkx.h.

La bibliothèque Gtk, sur laquelle repose l’environnement graphique de bureau gnome, est égalementdisponible sous (Windows) et permet donc le développement d’applications graphiques relativement porta-bles.

Qt est la bibliothèque graphique sur laquelle repose l’environnement graphique de bureau KDE. Initiale-ment propriétaire, elle est maintenant publiée sous une licence open source.

Tcl est un langage de script, i.e. permettant d’écrire des programmes exécutables sans compilation ;l’interprète tcl lit le script instruction après instruction, analyse chacune d’elles et exécute l’action corre-spondante. Tk offre une couche de présentation graphique au-dessus de tcl permettant le développementrapide d’applications graphiques.

SDL (Simple DirectMedia Layer) est une bibliothèque de programmation multimédia portable (GNU-Linux, Windows, Mac, *BSD... et même PSP !). Elle offre des abstractions pour manipuler les images 1D,le son, les périphériques de jeu (clavier/souris/manettes), et permet l’exécution de calculs parallèles. Elleest distribuée sous licence LGPL (en savoir plus sur SDL).

TÉLÉCOM SudParis — INF — Département Informatique — Mars 2014 — Télécom SudParis — 1ère année 11

Page 12: Télécom SudParis — 1ère année · 2014. 6. 4. · L’utilisateur peut, en général, interagir à tout moment avec l’application par le biais de la souris Le programme ne

Développement d’applications graphiques

# 11

'

&

$

%

2 Introduction à Gtk

2.1 Aperçu de la hiérarchie de widgets Gtk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122.2 Un exemple simple d’interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132.3 Programme Gtk en C pour cette interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142.4 Compilation d’une application Gtk en C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152.5 Concepteur d’interface Glade . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162.6 Description XML de l’exemple d’interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .172.7 Utilisation en C d’une description XML d’interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

Gtk est une bibliothèque couramment utilisée pour le développement sous GNU-Linux d’applicationsgraphiques, exploitables également sous Windows. Elle est à la base de nombreuses applications sous GNU-Linux (Gimp, Gnome...).

La hiérachie de widgets de Gtk comporte des classes très élaborées, comme par exemple GtkFileSelection,boîte de dialogue permettant la sélection graphique d’un fichier dans un système de fichiers, ou encoreGtkCTree, fenêtre permettant l’affichage d’un arbre dont l’utilisateur peut déployer les branches à volonté.

Glade est un outil graphique permettant le maquettage rapide d’interfaces graphiques simples. Il offreà la fois à l’utilisateur la possibilité de choisir visuellement dans une palette les widgets nécessaires à sonapplication, de les organiser et de spécifier leurs caractéristiques à travers des boîtes de dialogue pourconstruire progressivement son interface graphique.

On peut ainsi déterminer facilement l’arborescence de widgets à utiliser pour obtenir une interface sat-isfaisant le cahier des charges. L’outil Glade produit une description XML de cette arborescence qui estdirectement exploitable par Gtk, mais il est cependant vivement conseillé de construire l’interface par pro-grammation à l’aide d’appels à la bibliothèque Gtk pour créer l’arborescence de widgets déterminée avecGlade.

TÉLÉCOM SudParis — INF — Département Informatique — Mars 2014 — Télécom SudParis — 1ère année 12

Page 13: Télécom SudParis — 1ère année · 2014. 6. 4. · L’utilisateur peut, en général, interagir à tout moment avec l’application par le biais de la souris Le programme ne

Développement d’applications graphiques 2 Introduction à Gtk

# 12

'

&

$

%

2.1 Aperçu de la hiérarchie de widgets Gtk

GtkWidget+GtkMisc| +GtkLabel| ‘GtkImage+GtkContainer| +GtkBin| | +GtkButton| | +GtkWindow| | | ‘GtkDialog| | +GtkScrolledWindow| | ‘GtkViewport| +GtkBox| | ‘GtkButtonBox| ‘GtkPaned+GtkCalendar

Les types de widgets Gtk sont organisés en une hiérarchie d’héritage dont la racine est la classe GtkWidget(à noter que la racine de l’arborescence complète est en fait la classe GObject dont une des descendantes estla classe GtkObject, elle-même classe mère de GtkWidget).

Chaque type de widget dispose des caractéristiques de tous ses ancêtres dans la hiérarchie, et les primitivesd’une classe peuvent être appliquées aux widgets de toutes les classes descendantes. Un jeu de macros permetde considérer temporairement un widget comme élément d’une classe ancêtre, comme on le voit par exempledans le slide 2.3 avec la macro GTK_CONTAINER appliquée à une variable de type GtkWindow.

Chaque classe dispose d’une primitive de création de widget (e.g. gtk_window_new(), gtk_label_new(),etc) et d’un ensemble de primitives correspondant aux spécificités de la classe.

Gtk distingue deux types de conteneurs : ceux de la classe GtkBin et de ses sous-classes (en particulierGtkWindow), qui ne pouvent avoir qu’un seul widget enfant, et ceux des autres sous-classes de GtkContainer(comme par exemple GtkBox ou GtkTable), qui peuvent avoir plusieurs widget enfants et permettent de gérerla taille et la position relative des différents widget enfants.

Pour avoir un aperçu des widgets Gtk, le plus simple est de lancer l’outil Glade. Les widgets sont présentésdans une palette semblable à celle de la partie droite du slide, et il suffit de positionner le curseur de sourissur un widget pour obtenir son nom dans une pop up.

Pour avoir un aperçu de la programmation Gtk, on peut utiliser la commande gtk-demo qui regroupe unensemble de programmes de démonstration.

Quelques documents pour en savoir plus sur Gtk :Site officiel gtk (http://www.gtk.org/)Tutoriel gtk (http://library.gnome.org/devel/gtk-tutorial/)Site gtkFr (http://www.gtk-fr.org/wakka.php?wiki=PageAccueil)

TÉLÉCOM SudParis — INF — Département Informatique — Mars 2014 — Télécom SudParis — 1ère année 13

Page 14: Télécom SudParis — 1ère année · 2014. 6. 4. · L’utilisateur peut, en général, interagir à tout moment avec l’application par le biais de la souris Le programme ne

Développement d’applications graphiques 2 Introduction à Gtk

# 13

'

&

$

%

2.2 Un exemple simple d’interface

� Présentation :� Une fenêtre principale : widget de la classe GtkWindow� Une zone comportant un message : widget de la classe GtkLabel

� Comportement :� Un clic sur l’icone de fermeture de la fenêtre (événement delete-event)

fait quitter l’application

Cette interface simplissime va néanmoins permettre d’illustrer les principaux concepts de la program-mation avec Gtk : initialisation de la bibliothèque, création d’une fenêtre principale, enregistrement d’unefonction de rappel (callback), création d’un widget fils, affichage de l’interface, boucle de gestion des événe-ments.

Elle illustre également la différence entre widget conteneur et simple widget.

TÉLÉCOM SudParis — INF — Département Informatique — Mars 2014 — Télécom SudParis — 1ère année 14

Page 15: Télécom SudParis — 1ère année · 2014. 6. 4. · L’utilisateur peut, en général, interagir à tout moment avec l’application par le biais de la souris Le programme ne

Développement d’applications graphiques 2 Introduction à Gtk

# 14

'

&

$

%

2.3 Programme Gtk en C pour cette interface#include <gtk/gtk.h>void sortie(GtkWidget *widget, gpointer data) {

gtk_main_quit();}int main( int argc, char *argv[] ) {

GtkWidget *fenetre, *label;gtk_init( &argc, &argv );fenetre = gtk_window_new( GTK_WINDOW_TOPLEVEL ); // créationgtk_window_set_default_size( GTK_WINDOW(fenetre), 200, 100);g_signal_connect( G_OBJECT(fenetre), "delete_event", \

G_CALLBACK(sortie), NULL); // enregistrementlabel = gtk_label_new( "Hello World" );gtk_container_add( GTK_CONTAINER(fenetre), label);gtk_widget_show_all( fenetre ); // affichagegtk_main(); // boucle de gestion des evenementsreturn 0;

}

Un programme Gtk est constitué de la définition d’un ensemble de fonctions de rappel (callbacks) et d’unefonction principale reprenant la structure type d’une application graphique avec la fonction gtk_main() pourla boucle de gestion des événements. La fenêtre principale est désignée par GTK_WINDOW_TOPLEVELet le mapping d’un widget à l’écran est assuré par la fonction gtk_widget_show().

Le prototype d’une fonction de rappel est toujours le même :void myCallback(GtkWidget *widget, gpointer data)

L’enregistrement de l’association à un événement se fait au moyen de la fonction g_signal_connect() quiprend en argument le widget concerné, l’événement considéré, la fonction de rappel et un pointeur sur unedonnée utilisateur éventuelle (NULL si c’est inutile). Lorsque l’événement intervient, la fonction de rappel estappelée et deux informations lui sont transmises lors de cet appel et sont donc utilisables dans le corps de lafonction : le pointeur sur le widget, et le pointeur sur la donnée utilisateur référencé lors de l’enregistrementde l’association. Il est à remarquer que le nom de la fonction d’enregistrement est bien g_signal_connect()(et non gtk_signal_connect() qui correspond à une fonction obsolète).

La programmation Gtk demande de spécifier dans le détail les attributs des widgets constituant l’interface,donc de bien maîtriser la hiérarchie des widgets.

Il existe un certain nombre d’outils pour faciliter la construction d’interfaces graphiques, comme Gladepar exemple.

TÉLÉCOM SudParis — INF — Département Informatique — Mars 2014 — Télécom SudParis — 1ère année 15

Page 16: Télécom SudParis — 1ère année · 2014. 6. 4. · L’utilisateur peut, en général, interagir à tout moment avec l’application par le biais de la souris Le programme ne

Développement d’applications graphiques 2 Introduction à Gtk

# 15

'

&

$

%

2.4 Compilation d’une application Gtk en C

� GTK est un environnement complet et relativement complexe� Plus de 20 bibliothèques� Une dizaine de chemins d’accès pour les fichiers d’entête

� pkg-config pour la génération automatisée des options de compilation� pour la compilation séparéeI ‘pkg-config --cflags gtk+-3.0‘

� pour l’édition de liensI ‘pkg-config --libs gtk+-3.0‘

� Compilation + édition des liens, de l’exemplegcc -Wall hello-gtk.c -o hello-gtk ‘pkg-config --cflags --libsgtk+-3.0‘

L’utilisation de nombreuses bibliothèques impose l’inclusion de fichiers d’entête nombreux et disper-sés dans l’arborescence de fichiers. Pour faciliter la compilation, il existe heureusement la commandepkg-config. pkg-config détermine les informations nécessaires sur les bibliothèques installées sur le systèmeet permet de préparer les lignes de commande appropriées, l’utilisateur n’ayant à écrire qu’une commandegénérique.

Dans la commande gcc ci-dessus, nous utilisons le résultat de pkg-config (c.f. l’utilisation de ‘ ‘ dansle shell). L’option --cflags permet d’obtenir les options de compilation pour les répertoires des fichiersd’entête (génération des options -I), et l’option --libs les librairies (génération des options -l).

Exemple de résultat de la commande pkg-config :$ pkg-config --cflags --libs gtk+-3.0

-pthread -I/usr/include/gtk-3.0 -I/usr/include/atk-1.0 -I/usr/include/at-spi2-atk/2.0-I/usr/include/pango-1.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/cairo-I/usr/include/gdk-pixbuf-2.0 -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include-I/usr/include/harfbuzz -I/usr/include/freetype2 -I/usr/include/pixman-1-I/usr/include/libpng15 -I/usr/include/libdrm -lgtk-3 -lgdk-3 -latk-1.0 -lgio-2.0-lpangocairo-1.0 -lgdk_pixbuf-2.0 -lcairo-gobject -lpango-1.0 -lcairo -lgobject-2.0-lglib-2.0

Sur cet exemple, nous obtenons finalement la commande de compilation suivante :$ gcc -Wall hello-gtk.c -o hello-gtk -pthread -I/usr/include/gtk-3.0-I/usr/include/atk-1.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/pango-1.0-I/usr/include/gio-unix-2.0/ -I/usr/include/cairo -I/usr/include/gdk-pixbuf-2.0-I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -I/usr/include/harfbuzz-I/usr/include/freetype2 -I/usr/include/pixman-1 -I/usr/include/libpng15-I/usr/include/libdrm -lgtk-3 -lgdk-3 -latk-1.0 -lgio-2.0 -lpangocairo-1.0-lgdk_pixbuf-2.0 -lcairo-gobject -lpango-1.0 -lcairo -lgobject-2.0 -lglib-2.0

TÉLÉCOM SudParis — INF — Département Informatique — Mars 2014 — Télécom SudParis — 1ère année 16

Page 17: Télécom SudParis — 1ère année · 2014. 6. 4. · L’utilisateur peut, en général, interagir à tout moment avec l’application par le biais de la souris Le programme ne

Développement d’applications graphiques 2 Introduction à Gtk

# 16

'

&

$

%

2.5 Concepteur d’interface Glade

� Environnement de création d’interfaces graphiques basé sur la bibliothèque Gtk� évite de connaître les mécanismes internes de la bibliothèque graphique� permet d’obtenir rapidement des maquettes� décrit les interfaces graphiques dans des fichiers XML portables� ne donne certes pas directement accès à toute la souplesse de Gtk� mais autorise des solutions mixtes (Glade + programmation Gtk)

� Organisation type du développement d’une application avec Glade� production d’un fichier XML avec l’outil GladeI conception interactive de l’interface graphique et sauvegarde de sa description

� écriture de la fonction principale avec la structure typeI parsing du fichier XML : gtk_builder_add_from_fileI récupération de pointeurs sur des widgets : gtk_builder_get_objectI boucle Gtk habituelle de gestion des événements : gtk_main

� écriture usuelle des fonctions de rappel avec GtkI affichage/masquage de widget : gtk_widget_show/gtk_widget_hide

La construction d’une interface graphique par programmation en Gtk peut paraître laborieuse puisqu’ilfaut créer explicitement chaque widget, fixer ses propriétés et l’ajouter à son widget parent. L’intérêt deGlade est que le même résultat peut être obtenu en deux lignes de programme : ouverture d’un fichierXML et parsing du contenu du fichier. Le format du fichier XML étant défini au niveau de Gtk, celadonne la possibilité d’utiliser d’autres outils que Glade pour concevoir une telle interface graphique pour unprogramme Gtk.

Afin de pouvoir récupérer des pointeurs sur les widgets qu’il a besoin de manipuler dans son programme(par exemple dans la définition des fonctions de rappel), le développeur doit simplement connaître les nomsattribués à ces widgets par le concepteur de l’interface.

Mais attention : l’outil Glade n’est pas adapté à la construction d’interfaces graphiques complexes, commepar exemple lorsque de nombreux éléments similaires sont nécessaires (éléments de jeux, par exemple). Dansce cas, il permet juste d’obtenir rapidement une maquette réduite sans avoir besoin d’une connaissanceapprofondie de l’API Gtk. Il est donc judicieux de l’utiliser pour faire une première ébauche d’interface eneffectuant un choix visuel parmi les widgets disponibles dans Glade. Après validation de la maquette, uneprogrammation directe en Gtk peut bien entendu permettre de produire la même interface ; mais commeelle apporte davantage de contrôle et de possibilités au programmeur à travers les structures de contrôleuselles (conditionnelles, boucles...), une programmation entièrement en Gtk permet surtout de produireconfortablement une interface plus ambitieuse.

Historiquement, les premières versions de Glade généraient automatiquement un ensemble de fichierssources C comportant les appels aux primitives Gtk nécessaires pour produire l’interface telle que définiedans l’outil. L’approche Glade est devenue générique depuis la version 3 et n’impose plus un développementen C : l’interface créée est sauvegardée sous la forme d’un fichier au format XML, exploitable à partir de trèsnombreux langages de programmation grâce à une API intégrée à la bibliothèque Gtk (disponible depuis laversion 3.6 de Glade en lieu et place de la bibliothèque libglade utilisée précédemment). Cette API reposesur un objet Gtk auxiliaire de la classe GtkBuilder capable de parser un fichier XML.

Une interface graphique construite avec Glade est donc complétement portable.

Quelques documents pour en savoir plus sur Glade :Site officiel de glade (http://glade.gnome.org)Programmation Gtk avec glade (http://wingtk.sourceforge.net/ishan/glade.html)Petit tutoriel sur glade (http://franckh.developpez.com/tutoriels/gtk/gtkbuilder)

TÉLÉCOM SudParis — INF — Département Informatique — Mars 2014 — Télécom SudParis — 1ère année 17

Page 18: Télécom SudParis — 1ère année · 2014. 6. 4. · L’utilisateur peut, en général, interagir à tout moment avec l’application par le biais de la souris Le programme ne

Développement d’applications graphiques 2 Introduction à Gtk

# 17

'

&

$

%

2.6 Description XML de l’exemple d’interface

<?xml version="1.0"?><interface>

<!-- interface-requires gtk+ 3.0 --><!-- interface-naming-policy project-wide --><object class="GtkWindow" id="fenetre">

<property name="default_width">200</property><property name="default_height">100</property><signal name="delete_event" handler="gtk_main_quit"/><child>

<object class="GtkLabel" id="label"><property name="visible">True</property><property name="label" translatable="yes">Hello world</property>

</object></child>

</object></interface>

L’interface est constituée de deux widgets :

• un widget de la classe GtkWindow correspondant à la fenêtre principale, et• un widget fils de la classe GtkLabel dont la propriété label a pour valeur la chaîne de caractères “Hello

World”.

Chaque widget a un attribut chaîne de caractères nommé id qui permet de le désigner dans le programmeexploitant cette interface.

TÉLÉCOM SudParis — INF — Département Informatique — Mars 2014 — Télécom SudParis — 1ère année 18

Page 19: Télécom SudParis — 1ère année · 2014. 6. 4. · L’utilisateur peut, en général, interagir à tout moment avec l’application par le biais de la souris Le programme ne

Développement d’applications graphiques 2 Introduction à Gtk

# 18

'

&

$

%

2.7 Utilisation en C d’une description XML d’interface#include <gtk/gtk.h>int main( int argc, char *argv[] ) {

GtkBuilder *monBuilder;GtkWidget *maFenetre;gtk_init( &argc, &argv );monBuilder = gtk_builder_new();gtk_builder_add_from_file( monBuilder, "hello.glade", NULL);gtk_builder_connect_signals( monBuilder, NULL);maFenetre = GTK_WIDGET(gtk_builder_get_object(monBuilder, "fenetre"));gtk_widget_show_all (maFenetre);gtk_main();return 0;

}

� Génération automatisée des options nécessairesgcc -Wall hello-glade.c -o hello-glade ‘pkg-config --cflags --libsgtk+-3.0 gmodule-2.0‘

Le programme exploite, grâce à des appels aux fonctions de l’API GtkBuilder, la description de l’interfacecontenue dans le fichier XML produit par l’outil graphique Glade. Il peut comporter également desappels à des fonctions de la bibliothèque Gtk. L’analyse du fichier XML est réalisée par la fonctionngtk_builder_add_from_file() par l’intermédiaire d’un objet de la classe GtkBuilder créé par appel dela fonction gtk_builder_new().

C’est le nommage des widgets qui établit le lien entre l’interface décrite en XML et leur manipulationdans le programme. Précisément, la fonction gtk_builder_get_object() retourne un pointeur sur le widgetà partir de son identifiant (ici, “fenetre”) ; à noter l’utilisation de la macro GTK_WIDGET pour retyperen GtkWidget le GObject retourné par la fonction.

L’argument gmodule de pkg-config permet d’obtenir, lors de l’exécution, une édition des liens dy-namique correcte pour l’ensemble des symboles introduits dans la description au format XML et utilisés parle programme.

TÉLÉCOM SudParis — INF — Département Informatique — Mars 2014 — Télécom SudParis — 1ère année 19

Page 20: Télécom SudParis — 1ère année · 2014. 6. 4. · L’utilisateur peut, en général, interagir à tout moment avec l’application par le biais de la souris Le programme ne

Développement d’applications graphiques

# 19

'

&

$

%

3 Version graphique de l’application exemple

3.1 Organisation générale de l’application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203.2 Adaptation à réaliser pour gtk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213.3 Structure générale de la version graphique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223.4 Éléments de l’interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233.5 Interaction pour l’ajout d’un ouvrage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243.6 Interaction graphique pour l’ajout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253.7 Boîte de dialogue Ajout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263.8 Validation de la saisie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273.9 Récupération de la saisie. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .28

Cette section propose une présentation sommaire d’une version graphique de l’application exemple réaliséeprécédemment pour la modalité "terminal".

Partir d’une application en mode terminal pour obtenir une application graphique n’est pas nécessaire-ment une bonne idée et peut s’avérer très coûteux. Dans le cas de l’application exemple choisie, la structuresimple de l’application sous forme d’une boucle saisie/traitement facilite néanmoins l’adaptation. De plus,l’effet des actions de l’utilisateur au cours d’une session d’utilisation se trouve naturellement matérialisé dansle contenu du fichier texte data.txt listant les ouvrages ; il n’est donc pas nécessaire d’introduire de variablesà consulter/modifier par les callbacks pour refléter un quelconque état d’avancement dans le déroulement del’application. De façon générale, si on a le projet de passer d’une version en mode terminal à une versiongraphique, il sera plus facile de réutiliser en disposant d’une multitude de petites fonctions ciblées que d’unpetit nombre de très grosses fonctions.

La version graphique de l’application exemple ré-utilise tous les fichiers source génériques de la version"terminal" (main.c, menu.c, bibliotheque.c, ouvrage.c et util.c), et s’appuie sur la bibliothèque Gtk pourl’implantation de l’interaction graphique.

Avec une programmation purement Gtk, l’interface graphique est construite progressivement à l’aided’une succession d’appels à des fonctions de création de widgets notamment. Comme l’interface visée iciest assez basique, l’outil Glade peut être utilisé pour éviter d’entrer dans tous les détails de l’API Gtk etconstruire graphiquement l’interface de l’application. La mise en place de l’interface par le programme àpartir de la description XML est alors obtenue par un simple appel de fonction de l’API GtkBuilder.

Des indications complémentaires sont données pour une version purement Gtk, celle-ci étant égalementmise à disposition à titre d’exemple.

TÉLÉCOM SudParis — INF — Département Informatique — Mars 2014 — Télécom SudParis — 1ère année 20

Page 21: Télécom SudParis — 1ère année · 2014. 6. 4. · L’utilisateur peut, en général, interagir à tout moment avec l’application par le biais de la souris Le programme ne

Développement d’applications graphiques 3 Version graphique de l’application exemple

# 20

'

&

$

%

3.1 Organisation générale de l’application

nouvelleBibliotheque

suprimerBibliotheque

supprimerLesOouvragesDeAuteur

rechercherLesOuvragesDeAuteur

afficherBibliotheque

ajouterOuvrage

insererDansFichier

lectureFichier

choixRechercher

choixAjouter

choixAfficher

saisirAuteur

saisirOuvrage

afficher

main

afficherOuvrage

ouvrageToString

menu

init

quit

choix Supprimer

ecritureFichier

purge

menu−term.c

bibliotheque−term.c

ouvrage−term.c

menu.c

bibliotheque.c

ouvrage.c

fichierOuvrages.c

rechercherOuvrageDansCollection

supprimerOuvrageCollection

viderCollectionOuvrages

collectionOuvrages.cinsererOuvrageDansCollection

afficherCollectionOuvrages

Le découpage en modules qui a été adopté pour la version en mode "terminal" est mis en évidence sur legraphe d’appel :

• main, qui correspond à la fonction principale, avec le point d’entrée de l’application (initialisation,affichage d’un menu),

• menu, dédié à l’interaction utilisateur (affichage/saisie d’informations, boucle d’interaction avecl’utilisateur),

• bibliotheque, dédié à la gestion des collections d’ouvrages,• ouvrage, dédié à la gestion des ouvrages,• util, fonctionnalités de plus bas niveau liées au stockage de l’information (sur disque et en mémoire).

L’implantation des modules menu, ouvrage et bibliotheque amène à distinguer les opérations spécifiques àchaque modalité d’utilisation. Pour chacun de ces modules, les fonctions sont réparties dans deux fichierssources : l’un pour la partie générique, constituée des fonctions du module dont l’implantation est totalementindépendante des modalités d’interaction avec l’utilisateur, l’autre pour la partie spécifique à chaque modalitéd’interaction ("terminal" ou graphique).

Les noms des fichiers de la version en mode "terminal" comportant les fonctions spécifiques sont suffixéspar -term. Les fichiers correspondants de la version graphique seront dans la suite suffixés par -gtks’il n’utilisent que Gtk ou par -glade s’ils reposent également sur l’outil Glade. Ainsi, il y a un fichierbibliotheque-gtk.c utilisé à la fois par la version graphique avec Glade et par la version graphique purementGtk, mais les deux autres fichiers spécifiques sont distincts pour les deux versions graphiques : menu-glade.cet ouvrage-glade.c d’une part, ouvrage-gtk.c et menu-gtk.c d’autre part.

TÉLÉCOM SudParis — INF — Département Informatique — Mars 2014 — Télécom SudParis — 1ère année 21

Page 22: Télécom SudParis — 1ère année · 2014. 6. 4. · L’utilisateur peut, en général, interagir à tout moment avec l’application par le biais de la souris Le programme ne

Développement d’applications graphiques 3 Version graphique de l’application exemple

# 21

'

&

$

%

3.2 Adaptation à réaliser pour gtk

Entrées-sortie réalisées dans les différents modules :

� Fichier bibliotheque-gtk.c� afficherCollectionOuvrages() : printf()

⇒ gtk_text_buffer_insert*()� Fichier ouvrage-*.c

� afficherOuvrage(Ouvrage), afficherAuteur(Auteur) : printf()⇒ gtk_text_buffer_insert*()

� SaisieOuvrage(), SaisieAuteur() : fgets(), fscanf()⇒ gtk_entry_get_text() appliqué au widget zone de saisie

� Fichier menu-*.c� affiche() : printf()

⇒ gtk_text_buffer_insert*()� menu (Bibliotheque) : printf(), scanf()

⇒ gtk_text_buffer_insert*(), gtk_entry_get_text()

Initialisation de la bibliothèque Gtk avec gtk_init() : fonction init() dans menu-*.c

Les modalités d’entrée-sortie doivent être adaptées en s’appuyant sur les fonctionnalités de Gtk.L’interface comporte une zone d’affichage dans la fenêtre principale, sous la forme d’un widget de la classeGtkTextView. Tous les affichages effectués par des appels à printf() dans la version terminal seront réalisésdans cette zone d’affichage au moyen d’appel à des primitives de la famille gtk_text_buffer_insert*().Les saisies seront réalisées quant à elle par l’intermédiaire d’appels à gtk_entry_get_text() appliqués auxwidgets zone de saisie de la classe GtkEntry contenus dans les fenêtres de dialogue.

TÉLÉCOM SudParis — INF — Département Informatique — Mars 2014 — Télécom SudParis — 1ère année 22

Page 23: Télécom SudParis — 1ère année · 2014. 6. 4. · L’utilisateur peut, en général, interagir à tout moment avec l’application par le biais de la souris Le programme ne

Développement d’applications graphiques 3 Version graphique de l’application exemple

# 22

'

&

$

%

3.3 Structure générale de la version graphique

Fichier menu-glade.c :

� init()� initialisation de l’usage de la bibliothèque graphique

⇒ gtk_init()� menu()

� mise en place des éléments de l’interface graphique⇒ gtk_builder_new(), gtk_builder_add_from_file()

� association d’actions aux événements pertinents sur certains éléments⇒ gtk_builder_connect_signals()

� récupération de pointeurs sur les boîtes de dialogues et zones de saisie⇒ gtk_builder_get_object()

� affichage de l’interface⇒ gtk_widget_show()

� boucle de gestion des événements⇒ gtk_main()

L’essentiel de la structure de la version graphique de l’application exemple se retrouve dans les fonctionsdéfinies dans le fichier menu-*.c (menu-glade.c ou menu-gtk.c) :

• l’initialisation de la bibliothèque graphique est réalisée par la fonction init(), appelée par la fonctionmain() du fichier main.c

• la mise en place des éléments de l’interface, les associations "événement-action" et l’affichage del’interface sont réalisés par la fonction menu() (qui comporte également la boucle de gestion des événe-ments), elle aussi appelée par la fonction main().

La définition, de ces deux fonctions s’appuie sur l’API Gtk ; à noter que pour l’initialisation, la fonctiongtk_init_check() qui évite une sortie brutale du programme en cas d’échec de l’initialisation peut être utiliséeà la place de gtk_init().

Le slide précise les quelques fonctions utlisées dans la version Glade, alors que la version purement Gtkfait appel à davantage de fonctions, notamment pour la création des widgets des différentes classes.

La version Glade doit bien entendu utiliser la fonction gtk_builder_get_object(), qui retourne unpointeur sur un GObject à partir de son identifiant, pour faire le lien entre les widgets définis dans le fichierXML décrivant l’interface et ceux manipulés dans le programme C.

TÉLÉCOM SudParis — INF — Département Informatique — Mars 2014 — Télécom SudParis — 1ère année 23

Page 24: Télécom SudParis — 1ère année · 2014. 6. 4. · L’utilisateur peut, en général, interagir à tout moment avec l’application par le biais de la souris Le programme ne

Développement d’applications graphiques 3 Version graphique de l’application exemple

# 23

'

&

$

%

3.4 Éléments de l’interface graphique

L’interface graphique comporte une fenêtre principale avec des boutons permettant d’activer les fonction-nalités. Certaines fonctionnalités, comme par exemple la fonctionnalité d’ajout d’un ouvrage, vont entraînerl’affichage d’une boîte de dialogue pour la saisie d’informations complémentaires.

Chaque élément de l’interface doit être explicitement créé et mis en place si l’on n’utilise pas Glade,alors que sinon le chargement de l’interface décrite au format XML dans le fichier bibliotheque.glade metdirectement tous les éléments en place.

Les événements d’intérêt pour l’application vont provoquer l’exécution des fonctions de rappel (ou call-backs) associées.

Toutes les fonctions de rappel sont définies dans le fichier menu-*.c, et leurs identifiants ont le suffixeCall pour pouvoir mieux les distinguer des fonctions ordinaires.

TÉLÉCOM SudParis — INF — Département Informatique — Mars 2014 — Télécom SudParis — 1ère année 24

Page 25: Télécom SudParis — 1ère année · 2014. 6. 4. · L’utilisateur peut, en général, interagir à tout moment avec l’application par le biais de la souris Le programme ne

Développement d’applications graphiques 3 Version graphique de l’application exemple

# 24

'

&

$

%

3.5 Interaction pour l’ajout d’un ouvrage

nouvelleBibliotheque

suprimerBibliotheque

supprimerLesOouvragesDeAuteur

rechercherLesOuvragesDeAuteur

afficherBibliotheque

lectureFichier

choixRechercher

choixAfficher

saisirAuteur

afficher

main

afficherOuvrage

ouvrageToString

init

quit

choix Supprimer

ecritureFichier

purge

saisirOuvrage

menu−term.c

bibliotheque−term.c

ouvrage−term.c

menu.c

bibliotheque.c

ouvrage.c

fichierOuvrages.c

rechercherOuvrageDansCollection

supprimerOuvrageCollection

viderCollectionOuvrages

collectionOuvrages.c

afficherCollectionOuvrages

menu

choixAjouterajouterOuvrage

insererDansFichier

insererOuvrageDansCollection

A titre d’exemple, on focalise ici sur le cas d’utilisation de l’ajout d’un ouvrage, illustré sur le graphed’appel de la version terminal ci-dessus. Ce choix de l’utilisateur dans la fonction menu() produit un appelde la fonction générique choixAjouter() du module menu (fichier menu.c). Cette fonction générique choix-Ajouter() appelle alors la fonction spécifique saisirOuvrage() du module ouvrage (fichier ouvrage-term.c),puis la fonction générique ajouterOuvrage() du module bibliotheque (fichier bibliotheque.c) qui elle-mêmeappelle les fonctions insererOuvrageDansCollection() et insererDansFichier() du module util. On note icique la fonction saisirOuvrage() fait partie de la partie spécifique du module ouvrage alors que la fonctionajouterOuvrage() est une fonction générique du module bibliotheque.

L’approche événementielle de gtk s’appuie sur le mécanisme des fonctions de rappel, et l’interation setraduit donc par un graphe d’appel qui les fait intervenir explicitement (cf slide suivant).

TÉLÉCOM SudParis — INF — Département Informatique — Mars 2014 — Télécom SudParis — 1ère année 25

Page 26: Télécom SudParis — 1ère année · 2014. 6. 4. · L’utilisateur peut, en général, interagir à tout moment avec l’application par le biais de la souris Le programme ne

Développement d’applications graphiques 3 Version graphique de l’application exemple

# 25

'

&

$

%

3.6 Interaction graphique pour l’ajout

nouvelleBibliotheque

suprimerBibliotheque

supprimerLesOouvragesDeAuteur

rechercherLesOuvragesDeAuteur

afficherBibliotheque

lectureFichier

choixRechercher

choixAfficher

saisirAuteur

afficherOuvrage

ouvrageToString

choix Supprimer

ecritureFichier

purge

saisirOuvrage

afficher

ajouterOuvrageCall

main

quitCall

afficherSaisieAjoutCall

clic sur Valid clic sur Ajout

Affichage boite de dialogue

clic sur Quit

menu

init

bibliotheque−term.c

menu.c

bibliotheque.c

ouvrage.c

fichierOuvrages.c

rechercherOuvrageDansCollection

supprimerOuvrageCollection

viderCollectionOuvrages

collectionOuvrages.c

afficherCollectionOuvrages

choixAjouterajouterOuvrage

insererDansFichier

insererOuvrageDansCollection

ouvrage−*.c

...

...

Callbacks

menu−*.c

Avec la version graphique de l’application, l’activation de la fonctionnalité d’ajout d’un ouvrage se dérouleen deux temps :

• clic de l’utilisateur sur le bouton Ajout de la fenêtre principale, action qui provoque l’ouverture d’uneboîte de dialogue permettant à l’utilisateur de saisir les informations nécessaires (par l’intermédiairede l’exécution de la fonction de rappel afficherSaisieAjoutCall()),

• clic de l’utilisateur sur le bouton de validation de la boîte de dialogue, action qui déclenche l’ajouteffectif (dans la collection et le fichier) d’un ouvrage dont les attributs correspondent aux informationssaisies par l’utilisateur dans la boîte de dialogue (par l’intermédiaire de l’exécution de la fonction derappel ajouterOuvrageCall()).

Ces fonctions de rappel, définies comme toutes les autres dans le fichier menu-*.c, doivent être au préal-able associées aux événements concernés. Pour la version Glade, cette association est mise en place lorsdu démarrage de l’application par la fonction gtk_builder_connect_signals(), car tous les éléments del’interface sont présents dès le chargement de l’interface, y compris les différentes boîtes de dialogue. Leschoses sont donc un peu plus complexes pour la version purement Gtk puisque les boîtes de dialogue doiventêtre créées à la volée et les associations événement-callback mises en place à ce moment-là.

Les slides suivants détaillent les trois fonctions spécifiques à cette version graphique et impliquées dansl’interaction d’ajout d’un ouvrage : afficherSaisieAjoutCall()), ajouterOuvrageCall() et saisirOuvrage().Nota : on a pris soin de nommer toutes les fonctions de rappel par des identifiants se terminant par Callpour faciliter la lecture.

TÉLÉCOM SudParis — INF — Département Informatique — Mars 2014 — Télécom SudParis — 1ère année 26

Page 27: Télécom SudParis — 1ère année · 2014. 6. 4. · L’utilisateur peut, en général, interagir à tout moment avec l’application par le biais de la souris Le programme ne

Développement d’applications graphiques 3 Version graphique de l’application exemple

# 26

'

&

$

%

3.7 Affichage de la boîte de dialogue Ajout

bibliotheque.glade :

23 <object class="GtkButton" id="button1">24 <property name="label" translatable="yes">Ajout</property>28 <signal name="clicked" handler="afficherSaisieAjoutCall"/>136 <object class="GtkDialog" id="Ajout">

menu-glade.c :

dialogAjout = GTK_WIDGET(gtk_builder_get_object(builder,"Ajout"));

void afficherSaisieAjoutCall( GtkWidget *widget, gpointer data) {gtk_grab_add(dialogAjout); // prise de la capture par le widgetgtk_entry_set_text(titreEntry, ""); // vidage des differentsgtk_entry_set_text(auteurEntry, ""); // champs de saisie de textegtk_widget_show(dialogAjout); // affichage du widget

}

Les trois premières lignes extraites du fichier bibliotheque.glade montrent comment est défini le bouton“Ajout” (GtkButton) de la fenêtre principale de l’interface, et comment est établi le lien avec la fonction derappel afficherSaisieAjoutCall() associée au clic sur ce bouton. La quatrième ligne montre le début de ladéfinition du widget boîte de dialogue Ajout, avec l’identifiant “Ajout” qui est utilisé dans le programme Cpour la récupération d’un pointeur dialogAjout sur le widget, comme on le voit en dessous.

Le pointeur dialogAjout est une variable globale au fichier menu-glade.c qui initialisée dans la fonctionmenu() lors de la mise en place de l’interface. Il est ensuite utilisé par la fonction afficherSaisieAjoutCall()qui prépare le widget pour l’interaction avec l’utilisateur.

Comme pour tous les éléments de l’interface graphique, la représentation interne de la boîtede dialogue Ajout est présente en mémoire après l’appel, par la fonction menu(), de la fonctiongtk_builder_add_from_file() qui exploite la description XML de l’interface pour créer sa représenta-tion interne. La fonction de rappel afficherSaisieAjoutCall() associée au clic sur le bouton “Ajout” ne faitsimplement qu’afficher la fenêtre de dialogue (gtk_widget_show()), avec des champs de saisie vides (utili-sation de la fonction “accesseur” en écriture gtk_entry_set_text() avec une chaîne vide), et lui attribuerla capture (gtk_grab_add()). A noter que les variables globales titreEntry et auteurEntry sont égalementutilisées dans le fichier ouvrage-glade.c

La boîte de dialogue comporte un bouton de validation pour lequel le clic est associé à la fonction derappel ajouterOuvrageCall() décrite plus loin.

TÉLÉCOM SudParis — INF — Département Informatique — Mars 2014 — Télécom SudParis — 1ère année 27

Page 28: Télécom SudParis — 1ère année · 2014. 6. 4. · L’utilisateur peut, en général, interagir à tout moment avec l’application par le biais de la souris Le programme ne

Développement d’applications graphiques 3 Version graphique de l’application exemple

# 27

'

&

$

%

3.8 Validation des informations saisiesbibliotheque.glade :

165 <object class="GtkEntry" id="titreEntry">193 <object class="GtkEntry" id="auteurEntry">221 <object class="GtkSpinButton" id="anneeSpin">249 <object class="GtkButton" id="button6">250 <property name="label">gtk-ok</property>255 <signal name="clicked" handler="ajouterOuvrageCall"/>

menu-glade.c :

void ajouterOuvrageCall( GtkWidget *widget, gpointer data) {GtkWidget * dialogBox;Bibliotheque bibliotheque = (Bibliotheque) data;dialogBox = gtk_widget_get_toplevel(widget);choixAjouter(bibliotheque);gtk_widget_hide(dialogBox); // masquage du widgetgtk_grab_remove(dialogBox); // relâchement de la capture

}

Les lignes extraites du fichier bibliotheque.glade montrent une partie de la définition des widgets corre-spondant à la boîte de dialogue “Ajout” : les deux zones de saisie (GtkEntry), le bouton de sélection d’unevaleur dans un intervalle de valeurs (GtkSpinButton) et le bouton de validation (GtkButton) ; elles montrentégalement l’association de la fonction de rappel ajouterOuvrageCall() au clic sur ce dernier bouton.

Ainsi, un clic sur le bouton de validation déclenche l’exécution de la callback ajouterOuvrageCall() associéeà cet événement. Cette fonction récupère par gtk_widget_get_toplevel() un pointeur sur le widget boîtede dialogue “Ajout” (qui constitue le toplevel widget pour le bouton de validation), et appelle la fonctiongénérique choixAjouter(), définie dans le fichier menu.c ; au retour de cet appel, ajouterOuvrageCall() masquela boîte de dialogue (gtk_widget_hide()) et relache la capture(gtk_grab_remove()). On peut noter que,dans la version purement Gtk de l’application, le code de cette callback est plus court car elle se contente dedétruire la boîte de dialogue, celle-ci étant recréée lors de chaque usage; en revanche, le code déroulé par lacallback afficherSaisieAjoutCall() est plus conséquent puisque celle-ci doit construire une boîte de dialogue,ce qui est fait à travers un appel à la fonction générique afficherSaisieOuvrage().

Comme il apparaît sur le slide 3.6, la fonction choixAjouter() appelée par la callback ajouterOuvrageCall()appelle elle-même la fonction saisirOuvrage(), définie dans le fichier ouvrage-glade.c, qui ne fait quant à ellequ’exploiter les informations disponibles dans les champs de saisie de la boîte de dialogue pour construirel’ouvrage nécessaire au travail de ajouterOuvrage().

On peut noter l’utilisation du second paramètre de la fonction de rappel ajouterOuvrageCall() pour trans-mettre la donnée utilisateur bibliotheque, nécessaire pour l’appel de la fonction choixAjouter(). Ce paramètreest mis à disposition de la callback par le mécanisme de rappel car il a été transmis par la fonction menu()(menu-glade.c) lors de l’appel de fonction gtk_builder_connect_signals(builder, bibliotheque) quieffectue la connection des signaux présents dans la description de l’interface lors de sa mise en place.

Dans notre programme, toutes les fonctions de rappel utilisent cette même variable bibliotheque, initialiséelors du démarrage du programme (lecture du fichier) et mise à jour tout au long de son utilisation. Ilest à noter que si ces fonctions nécessitaient plusieurs informations (stockées dans différentes variables), ilfaudrait créer une structure de données qui regrouperait toutes ces informations. On pourrait ainsi passeren paramètre à gtk_builder_connect_signals() un pointeur sur cette structure unique pour permettre àchaque fonction rappel de récupérer les informations qui lui sont utiles.

TÉLÉCOM SudParis — INF — Département Informatique — Mars 2014 — Télécom SudParis — 1ère année 28

Page 29: Télécom SudParis — 1ère année · 2014. 6. 4. · L’utilisateur peut, en général, interagir à tout moment avec l’application par le biais de la souris Le programme ne

Développement d’applications graphiques 3 Version graphique de l’application exemple

# 28

'

&

$

%

3.9 Récupération des informations saisies

ouvrage-*.c :

Ouvrage saisirOuvrage() {Ouvrage ouvrage= {"sans titre","sans auteur",0};char tampon[TAILLE_MAX_TITRE+1];int annee;if ((titreEntry!=NULL) && (gtk_entry_get_text(titreEntry)!=NULL)){

strcpy( tampon, gtk_entry_get_text(titreEntry));if (strlen(tampon) > 0) strcpy( ouvrage.titre, tampon); }

if ((auteurEntry!=NULL) && (gtk_entry_get_text(auteurEntry)!=NULL)){strcpy( tampon, gtk_entry_get_text(auteurEntry));if (strlen(tampon) > 0) strcpy( ouvrage.nomAuteur, tampon); }

annee = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(anneeSpin));ouvrage.anneeEdition = annee;return ouvrage;

}

La récupération des informations saisies par l’utilisateur dans la boîte de dialogue est réalisée par lafonction saisirOuvrage(). Cette fonction, définie à l’identique pour les deux versions graphiques dans le fichierouvrage-*.c et appelée par la fonction choixAjouter(), n’est pas une callback mais une fonction ordinaire.Elle applique des fonctions “accesseurs” en lecture (*_get_*()) aux widgets de saisie pour récupérer lesinformations.

La bibliothèque Gtk propose en effet, pour la plupart des attributs des objets, des fonctions jouant le rôled’accesseurs en lecture (fonctions *_get_*()) ou en écriture (fonctions *_set_*()) : un accesseur en lecturepermet de consulter la valeur de l’attribut, un accesseur en écriture permet d’affecter sa valeur.

TÉLÉCOM SudParis — INF — Département Informatique — Mars 2014 — Télécom SudParis — 1ère année 29