Cours et exercice introduction à Visual C++
![Cours et exercice introduction à Visual C++](/images/remos_downloads/CoursInformatique-id3056.3056.pdf_thumb_prev.jpg)
TD 1 : Première rencontre avec Visual C++ et Qt Designer |
Les documents décrivant les TD mêlent des considérations générales qui vous aident à comprendre la logique des actions décrites et des instructions qui exigent que vous fassiez quelque chose. Pour vous permettre de distinguer facilement ces deux types d'informations (et, éventuellement, de bien repérer où vous en êtes), les instructions sont suivies d'une "case à cocher" vierge. Si vous travaillez avec une version imprimée du TD, vous pouvez donc cocher ces cases à mesure que vous effectuez les actions requises. Lorsqu'une commande doit être exécutée, elle est surlignée en mauve, alors que les indications relatives à l'endroit où elle se trouve sont surlignées en bleu. Par exemple : | ||||
Choisissez la commande | Quitter | dans le menu | Fichier | . |
Document du 29/01/04 -Retrouvez la version la plus récente sur
Comme tous les suivants, ce premier TD a pour objectif de vous permettre de créer un petit programme illustrant l'utilisation concrète des notions introduites dans la Leçon correspondante.
1 - Créer un programme sans savoir programmer ?
Nous avons, dans la Leçon 1, donné de la création d'un programme une description qui est résumée dans le tableau suivant :
Nom de l'opération | Produit | Responsable | Objectif |
Rédaction | Texte source | Programmeur (être humain) | Décrire la procédure à suivre pour parvenir au résultat souhaité |
Compilation | Code objet | Compilateur (programme) | Traduire le texte source en une suite d'instructions exécutables par le processeur visé. |
Edition de liens | Programme exécutable | Linker (programme) | Greffer sur le code objet tout ce qui lui manque pour devenir un programme exécutable dans le contexte visé. |
Les deux dernières opérations (compilation et édition de liens) sont effectuées par des programmes, et il nous suffira donc d'apprendre à lancer ceux-ci. La rédaction du texte source, en revanche, semble poser un problème actuellement insurmontable : c'est vous qui devriez en être responsable, et la Leçon 1 n'a pas même commencé à vous présenter le moindre rudiment de C++, langage dans lequel ce texte doit être écrit.
Pour comprendre pourquoi ce problème ne se pose pas réellement, il vous faut réaliser que les "petits" programmes que nous allons créer au cours des différents TD sont en fait d'une complexité monstrueuse. A l'exception de celui créé lors du TD2, ils se présentent en effet sous la forme de fenêtres affichées à l'écran et laissent à l'utilisateur différentes possibilités d'interaction, telles que le déplacement de la fenêtre en question sur l'écran, l'utilisation simultanée d'un autre programme, le choix arbitraire de l'ordre d'utilisation des éléments proposés dans la fenêtre (boutons, menus, etc.), ou la copie d'une information présentée dans la fenêtre en vue d'un collage dans un document géré par une autre application. De plus, ces programmes respectent les choix visuels généraux faits par l'utilisateur (couleur des fenêtres, taille de la police utilisée dans les menus, etc.).
Même en s'en tenant aux quelques fonctionnalités citées ci-dessus, la réalisation du moindre programme exigerait des efforts considérables (et quelques années d'études préalables) si nous devions assurer nous-mêmes intégralement la rédaction du texte source.
Pour contourner cette difficulté, les programmeurs utilisent différents types d'artifices :
- Les librairies d'interface graphique sont des collections de séquences de code exécutable qui assurent non seulement la représentation à l'écran des éléments d'interface communément utilisés (fenêtres, boutons, zones d'édition, etc.), mais également le fonctionnement élémentaire de ces éléments (déroulement des menus, détection du fait que l'utilisateur clique sur un bouton, etc.). Un programmeur disposant d'une telle librairie n'a donc pas à rédiger cette partie du programme : il lui suffit, pour pouvoir disposer des fragments de code contenus dans la librairie en question, de préciser au linker que celle-ci doit être liée (c'est-àdire incluse dans le programme exécutable).
- Les éditeurs d'interfaces se présentent comme des sortes de logiciel de dessin permettant de disposer à l'aide de la souris les différents éléments composant, par exemple, une fenêtre de dialogue. Ce qui les rend précieux est leur capacité à générer le texte source correspondant au dessin réalisé par le programmeur (ce texte source fait habituellement appel à une librairie graphique). Un programmeur disposant d'un éditeur d'interface n'a donc pas à rédiger la partie du programme qui crée une fenêtre et y dispose les divers boutons, zones d'édition et autres menus. Il lui suffit de compiler le texte généré par l'éditeur d'interface et d'indiquer au linker que le code objet correspondant doit être lié.
- Les générateurs d'applications sont des logiciels capables, à des degrés divers, de créer des portions de texte source correspondant à des parties du programme allant au-delà de la gestion des éléments de l'interface utilisateur. Dans sa version la plus rudimentaire, ce type d'outils n'est pas à proprement parler un générateur d'applications, mais un simple dispositif de choix entre différents squelettes d'applications préfabriqués assurant certaines fonctionnalités standard élémentaires. Le rôle du programmeur est ensuite d'habiller ce squelette, pour donner au programme les caractéristiques qui justifient son existence.
Le compilateur et le linker que nous allons utiliser sont ceux inclus dans l'environnement de développement Visual C++ 6.0.
En plus de ces programmes, nous allons utiliser Qt Designer 2.3, qui est à la fois un éditeur d'interfaces (utilisant la librairie Qt) et un petit générateur d'applications. Qt Designer et la librairie Qt sont des produits (développés par la société Trolltech) qui s'intègrent suffisamment dans l'environnement Microsoft pour que l'ensemble ainsi constitué soit tout à fait utilisable par des débutants. C'est l'utilisation de Qt Designer qui va vous permettre de réaliser ce premier TD sans écrire vous-même la moindre ligne de C++.
La procédure décrite ci-dessous suppose que Qt Designer ait été intégré dans Visual C++. 6.0
Les machines mises à votre disposition par le Centre Informatique pour les Lettres et les Sciences Humaines utilisent Qt 3.2. Si vous travaillez sur l'une de ces machines, cliquez ici pour sauter dans la bonne version du TD. Dans le cas contraire, si vous avez suivi les instructions du TD 0, votre machine doit être adaptée à ce qui va suivre.
A la différence d'autres activités utilisant un ordinateur (le traitement de textes, par exemple), la création d'un programme implique la mise en œuvre de plusieurs programmes différents (éditeurs, compilateur, linker, etc.) travaillant sur un ensemble de fichiers (textes sources, librairies, etc.). L'objet sur lequel nous allons travailler n'est donc pas un simple fichier (comme celui représentant le document en cours de rédaction, dans le cas du traitement de texte) mais un projet. Concrètement, un projet se présente comme une collection de fichiers habituellement regroupés dans un dossier portant le même nom que le projet. L'un de ces fichiers porte l'extension .dsw et permet à Visual C++ de "savoir quoi faire" des différents autres fichiers du projet. C'est l'ouverture de ce fichier qui correspond à l'ouverture du projet.
Si vous souhaitez modifier une lettre que vous avez écrite avec Word, par exemple, vous allez ouvrir le fichier dans lequel vous avez sauvé votre texte. Si vous souhaitez modifier un programme que vous avez créé avec Visual C++, il n'est en revanche pas question d'ouvrir le fichier qui contient ce programme. Cette ouverture déclencherait en effet l'exécution du programme en question, ce qui ne vous donnerait aucun moyen de le modifier. Pour améliorer un programme, il faut au contraire ouvrir le projet qui a débouché sur sa création, modifier le texte source, puis relancer le compilateur et le linker pour fabriquer un nouveau fichier (remarquez qu'il n'est pas nécessaire, ni même utile, de disposer du fichier .exe contenant l'ancienne version).
Pour des raisons techniques inavouables, les projets que nous allons créer doivent porter des noms ne comportant ni espaces ni minuscules accentuées.
Dans le cas présent, je vous suggère de choisir le nom TD01.
Le dossier portant le nom du projet et contenant les fichiers correspondants sera créé automatiquement lors de la création du projet. Il nous faut cependant choisir un emplacement convenable pour la création de ce dossier, et deux facteurs importants doivent être pris en compte :
- le compilateur peut être amené à créer des fichiers temporaires volumineux (plusieurs mégaoctets) dans le dossier projet ;
- les différents programmes utilisés (éditeurs, compilateurs, linker, etc.) ont fréquemment besoin d'accéder aux différents fichiers du projet.
Le premier facteur INTERDIT d'envisager la création d'un projet sur une disquette. Le second suggère fortement de choisir un disque dur local plutôt qu'une unité accessible via un réseau ou un disque local peu rapide (disque zip, par exemple).
Quel que soit votre choix, il faut savoir que le dossier dans lequel le dossier projet va être créé : - doit déjà exister (il ne sera pas créé automatiquement en même temps que le dossier projet) ;
- ne doit pas déjà contenir un dossier portant le nom choisi pour le projet (ce qui rendrait impossible la création automatique du dossier projet) ;
- doit, de préférence, contenir un fichier (qui facilitera la désignation du dossier).
Une option simple est de créer un dossier nommé "Mes_projets_Qt" et d'y enregistrer un fichier texte vide nommé "", par exemple.
Après avoir lancé Visual C++ , la création d'un nouveau projet est obtenue simplement en cliquant sur le bouton (New Qt Project) . La boîte de dialogue "New Project" s'ouvre alors (cf. ci-contre).
Il faut ensuite indiquer le nom du projet et l'emplacement où le dossier qui va recevoir les fichiers relatifs à ce projet doit être créé.
Le "type d'application" créé par défaut est un "Dialog", ce
qui convient parfaitement à notre propos. Il suffit donc maintenant de cliquer sur le bouton "OK" .
Le dialogue "Nouveau projet Qt"
Le dialogue de création d'un projet QT comporte plusieurs imperfections. Tout d'abord, la zone "Location" affiche un chemin qui n'existe pas encore, puisqu'il comporte le nom du dossier projet qui va être créé. De plus, l'utilisation du bouton "…" déclenche l'apparition d'un dialogue d'ouverture de fichier, qui exige donc que l'on désigne un fichier. En clair : on doit spécifier l'emplacement du dossier qui va être créé en désignant un fichier existant déjà (la nature de ce fichier est sans importance, il n'intervient que comme un truchement permettant de désigner le dossier qui le contient). Si vous avez pris la précaution de créer un fichier "", désigner le dossier qui le contient comme étant l'emplacement choisi pour le futur dossier projet est très facile. En revanche, si l'emplacement où vous souhaiter créer votre dossier projet ne contient aucun fichier désignable, il vous faudra ignorer le bouton "…" et taper le chemin complet de cet emplacement dans la zone d'édition "Location".
En cas de problème, refermez Visual C++ et QT Designer, effacez le dossier éventuellement créé et recommencez la procédure à partir du début…
3 - Création du programme
La création d'un "projet Qt" provoque le lancement de Qt Designer. L'interface utilisateur de cette application comporte plusieurs fenêtres et barres d'outils (cf. figure ci-dessous).
La fenêtre intitulée "TD01" est une représentation de l'interface que le programme que nous allons créer proposera à ses utilisateurs. C'est donc dans cette fenêtre que nous allons disposer les différents éléments d'interface que nous souhaitons utiliser.
Les éléments composant une interface graphique (boutons, menus, zones d'éditions, etc.) sont | ||||
appelés des | widgets | , ou dans la terminologie propre à Windows, des | contrôles | . |
Lorsque l'un des widgets présents dans notre projet d'interface est sélectionné, la fenêtre "Property Editor" affiche des données le concernant, ce qui va nous permettre de donner à notre interface les caractéristiques exactes que nous souhaitons.
L'interface utilisateur de Qt Designer
Dans la fenêtre "TD01", cliquez sur la zone de texte "Place your widgets here!" .
Dans la fenêtre "Property Editor", repérez la ligne intitulée "text" et cliquez dans la colonne "Value", de façon à pouvoir modifier ce texte
Effacez le texte proposé par Qt Designer et tapez un message de votre cru (cf. exemple ci-contre)
Le texte que vous avez tapé devrait maintenant apparaître dans la fenêtre "TD01", en lieu et place du message originel. Ajustez, si nécessaire, la taille de cette zone de texte, de façon à ce que votre message apparaisse intégralement .
Il est maintenant temps de générer le programme correspondant aux spécifications que nous venons de donner. Comme cette tâche est du ressort de Visual C++ et non de Qt Designer, il nous faut faire en sorte que les informations collectées par ce dernier soient rendues disponibles pour le compilateur. Il suffit pour cela d'enregistrer le résultat de vos efforts (Menu File de Qt Designer, commande Save) .
Avant de compiler un programme, il ne faut pas oublier de sauvegarder les modifications faites à son interface à l'aide de Qt Designer.
Dans la barre de tâches, cliquez sur l'icône représentant un anneau de Moebius coloré, de façon à retourner dans Visual C++ .
L'icône de
Il est inutile de refermer Qt Designer, nous allons encore en avoir besoin. Visual C++ Vous devez donc vous retrouver face à Visual C++ :
L'interface utilisateur de Visual C++
La compilation de tous les fichiers source et l'édition des liens peuvent être déclenchés par une commande unique : dans le menu Build, choisissez la commande "Build " (ou, si vous êtes paresseux, contentez-vous d'appuyer sur la touche F7) .
Après quelques instants de traitement, la fabrication de notre programme s'achève et Visual C++ nous propose un petit rapport d'activité :
Un "rapport d'activité" de Visual C++
Ce rapport indique que des traitements préalables (Uic et Moc) ont tout d'abord été effectués sur les fichiers créés par Qt Designer ( et td01dialog.h). Cinq fichiers contenant du texte source en C++ ont ensuite été compilés (ce sont les fichiers portant l'extension .cpp). La création du programme s'est achevée par l'invocation du linker, qui est parvenu à générer le programme sans qu'aucun problème n'ait été détecté.
Pour essayer le programme qui vient d'être créé, pressez la touche F5 .
Une fois lassé d'admirer une scène analogue à celle représentée ci-contre, vous pouvez refermer le programme en cliquant sur la case de fermeture du dialogue qui constitue sa fenêtre principale .
Refermer la fenêtre principale d'un programme de type "dialog" met fin à l'exécution de celui-ci. Exécution de la première version
Maintenant que nous avons une bonne idée du processus général de création d'un programme, nous pouvons envisager de donner à notre projet des fonctionnalités un peu plus attrayantes que le simple affichage d'un message, aussi encourageant soit-il.
Dans la barre de tâches de Windows, cliquez sur l'icône , de façon à retourner dans Qt Designer .
Si vous avez refermé Qt Designer, son icône n'apparaît plus dans la barre de tâches de Windows. Vous pouvez rétablir la situation de la façon suivante : dans l'onglet "File View" de la fenêtre "Workspace" de Visual C++, double-cliquez sur le fichier . (si la fenêtre Workspace est elle-même invisible, vous pouvez la faire apparaître à l'aide de la commande du même nom proposée dans le menu View de Visual C++).
Si le chemin d'accès à votre dossier projet comporte des espaces, Qt Designer ne parvient pas à ouvrir directement le fichier .ui et vous propose un (ou plusieurs) dialogue(s) de création de fichier. Refermez ces dialogues (bouton [Annuler]) et utilisez la commande "Open" du menu "File" pour ouvrir votre fichier .
Dans le menu "Tools" de Qt Designer, choisissez l'option "Input" et, dans le sous-menu qui apparaît alors, la commande "Slider" .
Placez votre pointeur de souris quelque-part dans la région supérieure gauche de notre projet d'interface, enfoncez le bouton gauche de la souris et, tout en maintenant ce bouton enfoncé, faites glisser la souris vers le bas et vers la droite . Vous venez d'ajouter un widget de type "slider" à notre projet d'interface, qui doit maintenant ressembler à l'image présentée ci-contre.
Après avoir créé un widget, vous pouvez en changer la taille et la position, ou même le supprimer (sélectionnez le widget et appuyez sur la touche "d'effacement à droite").
Les "sliders" permettent à l'utilisateur d'un programme d'effectuer certains réglages, un peu comme un potentiomètre linéaire peut permettre à l'utilisateur d'un amplificateur d'ajuster le volume sonore. Du point de vue du programmeur, un slider se caractérise par une valeur entière, qui indique dans quelle position l'utilisateur a placé le curseur.
L'objectif de notre deuxième version du projet est simplement d'afficher cette valeur. Pour cela, nous devons introduire un second widget dans notre interface.
Dans le menu "Tools" de Qt Designer, choisissez l'option "Display" et, dans le sous-menu qui apparaît alors, la commande "LCDNumber" .
Positionnez ce widget au-dessus du message affiché dans notre projet d'interface, qui doit maintenant ressembler à l'image présentée ci-contre .
Il nous reste maintenant à exprimer l'idée que, lorsque le slider est déplacé, il doit signaler au LCDNumber que la valeur à afficher n'est plus la même.
Dans le menu "Tools", sélectionnez la commande "Connect Signal/Slots"
Amenez le curseur de la souris (qui est maintenant une croix, et non plus une flèche) sur le slider, enfoncez le bouton gauche et, et, tout en maintenant ce bouton enfoncé, faites glisser la souris vers le LCDNumber. Lorsque vous relâchez le bouton de la souris dans le LCDNumber , le dialogue de connexion signal/slot apparaît (cf. ci-contre).
Ce dialogue propose une liste des signaux que le slider est capable d'émettre, une liste des actions que le LCDNumber est capable d'effectuer en réponse à ces signaux, et un
tableau (vide, pour l'instant) récapitulant les liens existant entre les deux widgets. Le dialogue de connexion signal/slot
Dans la liste des signaux, sélectionnez "valueChanged(int)" .
Nous souhaitons, en effet, que le slider signale tout changement de la valeur correspondant à la position de son curseur.
Dans la liste des slots (que l'action précédente a modifiée), sélectionnez "display(int)" .
Nous souhaitons, en effet, que le LCDNumber affiche (en anglais : to display) la valeur reçue.
La connexion que nous venons d'établir apparaît alors dans le tableau récapitulatif, et nous pouvons donc cliquer sur le bouton "OK" pour refermer le dialogue .
En vous inspirant des instructions suivies lors de la mise au point de la première version, générez et essayez cette seconde version de notre programme.
Modifiez notre projet d'interface pour qu'il ressemble à l'image ci-contre .
Le widget situé à droite de la fenêtre est de type "dial" et est proposé sous la rubrique "Input" du menu "Tools".
Pour améliorer la lisibilité, vous pouvez modifier la propriété "font" du widget affichant votre texte, ainsi que les propriétés "numDigits" et "segmentStyle" du
LCDNumber.
Créez une connexion pour que les mouvements du curseur se traduisent non seulement par l'affichage de la valeur numérique correspondant à sa nouvelle position, mais aussi par un déplacement de l'aiguille du quadrant .
Le "slot" du dial qui permet de fixer la position de l'aiguille s'appelle "setValue(int)".
En vous inspirant des instructions suivies lors de la mise au point de la première version, générez et essayez cette troisième version de notre programme. Que se passe-t-il lorsque vous utilisez la souris pour déplacer directement l'aiguille du quadrant ?
4 - Interrompre et reprendre le travail sur un projet
Refermez Visual C++
Retrouvez votre dossier projet et ouvrez-le
Outre une quinzaine de fichiers nécessaires à la construction de notre programme, ce dossier contient un sous-dossier nommé Debug, qui a été créé pour recevoir les fichiers créés pendant la construction de notre programme.
Ouvrez le sous-dossier Debug
Deux des fichiers contenus dans ce sous-dossier sont particulièrement remarquables. L'un, qui porte l'extension .pch, est d'une taille considérable (supérieure à la somme des tailles de tous les autres fichiers du dossier projet !). L'autre, qui porte l'extension .exe, contient le programme que nous venons de créer, comme vous pouvez le constater en double-cliquant dessus .
Le contenu du dossier projet Le contenu du sous-dossier Debug
Refermez notre programme et jetez le sous-dossier Debug à la poubelle .
Le dossier Debug ne contient que des fichiers créés automatiquement lorsque nous lançons la compilation et l'édition de liens. Dans la mesure ou nous conservons les autres fichiers du dossier projet, le contenu du sous-dossier Debug n'a rien d'indispensable : si nous souhaitons recréer ces fichiers, il nous suffit de presser F7 dans Visual C++….
La taille du dossier projet est maintenant plus raisonnable (une centaine de kilo-octets, dans le cas présent) et, en cas de besoin, vous pouvez parfaitement le copier sur une disquette.
Pour reprendre un projet interrompu, le plus simple est d'ouvrir le dossier projet et de doublecliquer sur le fichier .dsw qu'il contient .
Cette action a pour effet d'ouvrir le projet avec Visual C++ et, comme nous l'avons vu, un double-clic sur le fichier portant l'extension .ui (onglet FileView de la fenêtre Workspace) ordonne à QT Designer de reprendre le travail sur notre projet d'interface.
5 - Exercice
La troisième version de notre programme n'a pas, nous l'avons vu, un fonctionnement très satisfaisant lorsque l'utilisateur manipule directement l'aiguille du quadrant : ni la valeur affichée par le LCDNum ni le curseur du slider ne suivent le mouvement, ce qui provoque un saut de l'aiguille fort disgracieux lorsqu'on déplace ensuite le curseur du slider.
Corrigez ces problèmes .
Ce que les anglophones appellent "an application framework".