Université de Strasbourg UFR de Mathématiques et d Informatique Département d Informatique Licence 3 d Informatique IHM Année 2010 2011 TP 02 : Création d un projet Qt Résumé Objectif des TP est de créer un petit programme de dessin de triangles en utilisant la librairie d outils graphique Qt. L objectif de ce TP est de prendre en main le processus de création de projet reposant sur Qt dans sa version 4. Et de créer les premières fenêtres de l application. Pensez à consulter la documentation de la librairie Qt sur le site internet http://doc.trolltech.com/ ou en utilisant le programme Qt Assistant (en lançant la commande assistant). 1 Mise en place du projet Pour débuter ce projet, nous allons créer la fenêtre principale de l interface, son implémentation et un fichier de projet Qt destiné à l outil de compilation de Qt. 1.1 Création de la fenêtre principale de l interface La création de la fenêtre principale se fait via le Designer Qt (commande designer). Créez un nouveau fichier et choisissez le template Main Window. Dans l éditeur de propriétés, nommer l objet QMainWindow (par exemple DrawTriangleMainWindow, cf. Figure 1). Sauvegarder le fichier dans le dossier contenant votre projet (par exemple, drawtrianglemainwindow.ui) Figure 1 QT designer. Création de la fenêtre principale de l application. 1
#ifndef _MAINWINDOW_H_ #define _MAINWINDOW_H_ /* Inclure le fichier ui_<nom du fichier ui de votre widget>.h Nécessaire pour indiquer à qmake de compiler le fichier ui de description du widget */ #include "ui_drawtrianglemainwindow.h" /* Définition de la classe MainWindow qui sera utilisée dans le projet. Cette classe dérive d une part de la classe QMainWindow et de la classe générée par uic lors de la compilation de votre fichier.ui */ class MainWindow : public QMainWindow, private Ui::DrawTriangleMainWindow { Q_OBJECT //Indique à qmake de traiter ce fichier comme un fils de QObject // (nécessaire pour le mécanisme de signaux) public: //Définition standard du constructeur (reprenant les arguments du constructeur // de QMainWindow) MainWindow(QWidget * parent = 0, Qt::WindowFlags flags = 0); ~MainWindow(); //Destructeur standard }; #endif Figure 2 Déclaration de la classe MainWindow dans le fichier mainwindow.h. 1.2 Fichier d implantation de la fenêtre principale Le principe est le suivant : Le fichier.ui, créé dans le designer, est compilé via l utilitaire uic. Un fichier.h est généré qui portera le nom ui <nom du fichier ui>.h (dans notre exemple, on obtient un fichier ui drawtrianglemainwind Dans ce fichier.h, une classe est définie qui porte le nom donné au widget principal du fichier ui (DrawTriangleMainWindow dans notre exemple). Cette classe implante tout ce qui a été dessiné et défini dans le designer. On crée une classe (MainWindow, dans notre exemple) qui hérite à la fois de la classe Qt représentant une fenêtre principale (QMainWindow) et de la classe qui est générée à partir du fichier ui (donc la classe DrawTriangleMainWindow dans notre exemple). Pour que notre classe MainWindow puisse émettre et recevoir des signaux, il faut invoquer la macro Q OBJECT lors de la définition de la classe. 1.3 Fonction main et affichage de la fenêtre Pour lancer notre programme, nous allons maintenant définir la fonction main. Cette fonction très simple va seulement effectuer la chose suivante : 1. Initialiser Qt en créant une QApplication. 2. Créer une instance de MainWindow 3. Afficher la fenêtre. 4. Lancer la boucle principale d attente des événements. La Figure 4 donne le code de la fonction main utilisé pour démarrer le programme. 1.4 La compilation Pour compiler un projet bâti avec la librairie Qt, certaines opérations supplémentaires doivent être effectuées. En effet, le mécanisme de communication, basé sur le signaux, n est pas standard en C++. Il nécessite une phase de précompilation. Les classes C++ dans lesquelles on a invoqué la macro Q OBJECT sont ainsi passé au précompileur Qt (utilitaire moc). 2
#include "mainwindow.h" /* Implémentation de constructeur. Appel les constructeur de QMainWindow et de la classe DrawTriangleMainWindow générée par uic à partir du fichier.ui */ MainWindow::MainWindow(QWidget * parent, Qt::WindowFlags flags) : QMainWindow(parent, flags), Ui::DrawTriangleMainWindow() { setupui(this); //Obligatoire pour initialiser les éléments de l interface } MainWindow::~MainWindow() { } Figure 3 Implantation de la classe MainWindow dans le fichier mainwindow.cpp. #include <QtCore> #include "mainwindow.h" int main(int argc, char ** argv, char **arge) { //Initialise Qt en créant une QApplication QApplication app(argc, argv); //Crée une fen^etre principale MainWindow mw; mw.show(); //Affiche la fen^etre principale //Lance la boucle d attente d événements de l application Qt //Nécessaire pour gérer les événements liés à l interface graphique return app.exec(); } Figure 4 Fonction main de lancement du programme. 3
# Définit le type de projet (application, librairie,...) # Ici, une application standard TEMPLATE = app # Définit le nom de l exécutable généré TARGET = drawtri # Définit les options de configuration de la compilation # Utilisation des fonctionnalitéq de qt, affichage d avertissements de compilation # Compilation en mode debug (autre possibilité release) CONFIG += qt \ warn_on \ debug # Liste les fichiers en-t^ete du projet HEADERS += mainwindow.h # Liste les fichiers sources du projet (attention au \ en fin de ligne!) SOURCES += mainwindow.cpp \ drawtri.cpp # Liste les fichiers de description d interface.ui du projet FORMS += drawtrianglemainwindow.ui Figure 5 Fichier.pro minimaliste pour compiler le projet. Cette étape, ainsi que la compilation des fichiers d interface graphique complexifie la compilation des projets. Afin d automatiser cela, Qt dispose d un générateur de fichier Makefile : l utilitaire qmake. qmake se base sur la description d un projet, définie dans un fichier.pro. Dans ce fichier sont regroupés les noms des fichiers qui composent le projet (sources, ui,...), les options de compilation souhaités, les librairies à inclure, etc. La Figure 5 donne un fichier.pro minimaliste permettant de compiler le projet présenté en exemple. L invocation de qmake dans le répertoire contenant le fichier.pro déclenche la génération d un fichier Makefile directement utilisable pour compiler le projet. Chaque modification du fichier.pro nécessite de mettre à jour le Makefile et par conséquent de rappeler qmake. En générant le Makefile via qmake, puis en compilant puis en exécutant le programme généré, vous devriez obtenir un résultat semblable à la Figure 6. 2 Création des menus La création des menus s effectue directement dans le designer. Il suffit de taper le nom du menu désiré à l endroit où se trouve la mention Type Here de la fenêtre en cours d élaboration (cf. Figure 1). Créer 4 menus différents : Fichier, Affichage, Options et Aide. Dans l inspecteur d objet du designer, vous constatez que 4 nouveaux objet de type QMenu se sont ajoutés. En utilisant l éditeur de propriétés, nommé ses objets avec un nom plus parlant (par exemple filemenu pour le menu Fichier ). C est ce nom là qui sera utilisé dans le code. De la même manière que pour les menus, on va maintenant ajouter différents éléments aux menus : Menu Fichier : Nouveau, Ouvrir, Sauvegarder et Quitter. Menu Options : Épaisseur trait, Couleur et Gestion des triangles. Menu Aide : Version. Vous constaterez que des objets de type QAction sont apparus dans l inspecteur d objets du designer. Les items de menu sont en effet représentés par des objets de type QAction. Renommez ces nouvelles actions de façon plus parlantes 1. Grâce à l éditeur de propriétés, ajouté des raccourci clavier pour les actions Nouveau (Ctrl+N), Ouvrir (Ctrl+O), Sauvegarder (Ctrl+S) et Quitter (Ctrl+Q). Les actions peuvent également être avec marque (checkable). Ajouter au menu Affichage, une action checkable intitulé Barre d outils qui permettra, par la suite d afficher ou de masquer la barre d outils. Cette 1. Si nécessaire! 4
Figure 6 Résultat de la première compilation action doit être activée au démarrage de l application. L élément Gestion des triangles doit être grisé par défaut au démarrage de l application. Ajouter des séparateurs entre Nouveau et Ouvrir et entre Sauvegarder et Quitter. Afin d aider l utilisateur, ajoutez des bulles d aide (tooltips) qui s affiche au passage de la souris sur une action et permettant d afficher du texte. Vous pouvez recompiler votre programme pour voir l effet de ces modifications sur votre programme. Cliquez sur Barre d outils pour contrôler le fonctionnement du changement d état. Vous pouvez également regarder le fichier générer par uic. 2.1 Ajout d icônes Afin d embellir l application, nous allons ajouter des icônes à certains items du menu. 2.1.1 Ressource manager Qt offre un mécanisme permettant de regrouper des fichiers au sein d un seul afin d en faciliter l utilisation. De plus ces fichier seront intégrés à l exécutable ce qui permet de faciliter la distribution de l application. Le designer Qt permet de créer des fichiers ressource (extension.qrc) via le Ressource browser. Ces fichiers peuvent aussi être édité via un éditeur de textes (simple fichier xml). Pour en créer un dans l explorateur de ressource cliquer sur l icône éditer ressources, puis sur l icône Nouveau fichier Ressources. Créer un nouveau fichier. Ajouter un nouveau préfixe (nommé icones, par exemple) puis ajouter les fichiers images que vous trouverez à cette adresse : TODO. Afin que le projet puisse compiler en intégrant le fichier de ressources, ajouter au fichier.pro une règle permettant d ajouter des fichiers de ressources 2 : RESOURCES += icons.qrc Pour ajouter les icônes aux actions, utiliser par l éditeur de propriété du designer et choisir les images depuis un fichier ressource. Recompiler et relancer votre programme 3. 3 Barre d outils Nous allons maintenant ajouter une barre d outils à notre interface. Pour cela, dans le designer, clique droit sur la fenêtre puis Add toolbar. Une barre d outils vide s ajoute à votre interface. 2. Adapter le nom à celui que vous avez donné à votre fichier de ressources. 3. N oublier pas de regénérer le Makefile 5
Figure 7 Résultat après l ajout de la barre d outils Figure 8 Fenêtre dialogue Version Pour ajouter des boutons sur l interface, Qt offre la possibilité d utiliser les actions définies pour le menu. Pour cela dans le designer, ouvrir l éditeur d actions. Pour ajouter une action à la barre d outil, il suffit de prendre l action depuis l éditeur d actions et de la glisser sur la barre d outils. Pour ajouter un séparateur entre les outils, il suffit de faire un clique droit sur la barre d outil et de choisis Append separator 4 Ajouter les actions Nouveau, Ouvrir, Sauvegarder et une nouvelle action Dessiner et qui doit être checkable. Ajouter un séparateur entre la 3 e et la 4 e action. Tester votre projet, vous devez obtenir un résultat semblable à celui de la Figure 7. 4 Boîtes de dialogue supplémentaires 4.1 Affichage de la version Nous allons maintenant créer une boîte de dialogue pour afficher la version du logiciel. Elle devra ressembler à la capture de la Figure 8. Créer une nouvelle forme dans le designer Qt. Choisissez le modèle Dialogue sans bouton. Ce dialogue doit être modal. Déposer dans la fenêtre de la boîte de dialogue un label (QLabel) puis un bouton (QPushButton). Penser à renommer les widgets créés. Mettre le texte Version 0.1 pour le label (propriété text ) et Ok pour le bouton. Afin de positionner correctement les widgets dans la fenêtre, nous allons associer un layout à la fenêtre. Il en existe de plusieurs type, nous allons choisir le layout vertical. Pour cela, clique droit sur la fenêtre, Layout Lay Out Vertically. Vous pouvez réduire la taille de la fenêtre afin de visualiser le comportement du layout choisi. Sur le même principe que pour la fenêtre principale, il faut maintenant créer une classe pour implanter la boîte de dialogue créer. Procéder de la même façon qu au point 1.2. La seule différence réside dans le fait que 4. Il possible de repositionner les séparateurs en les glissant vers leur nouvelle position. 6
Figure 9 Dialogue Épaisseur Figure 10 Dialogue de choix de couleurs la classe créée doit hériter de QDialog et non plus de QMainWindow. Penser à vérifier les arguments requis par le constructeur de QDialog dans la documentation. Ajouter ces fichiers au fichier.pro et recompiler. Si vous souhaitez tester votre dialogue, ajouter à la fonction main les instructions suivantes après la création et l ouverture de la fenêtre principale : VersionDialog tmp(&mw, Qt::Dialog); tmp.show(); 4.2 Dialogue Épaisseur Réaliser le dialogue de la Figure 9 en utilisant les widgets suivants : Dialogue avec boutons et modal. QSpinBox sans boutons et px en suffix. 3 QLabel. QSlider avec graduation en dessous. Grid Layout. 4.3 Dialogue Choix de couleurs Réaliser le dialogue de la Figure 10 en utilisant les widgets suivants : Dialogue avec boutons, modal et un layout vertical. 1 QLabel. 1 QGroupBox avec un layout vertical. 3 QRadioButton dans le QGroupBox. 4.4 Gestion des triangles Réaliser le dialogue de la Figure 11 en utilisant les widgets suivants : Dialogue sans bouton, modal et layout horizontal. 1 QLabel et 1 QListView dans un layout vertical. 7
Figure 11 Dialogue de gestion des triangles Figure 12 Dialogue des propriétés des triangles 3 QPushButton dans un layout vertical avec 2 spacers verticaux. 4.5 Propriétés des triangles Réaliser le dialogue de la Figure 12 en utilisant les widgets suivants : Dialogue avec boutons, modal et un layout grille. 2 QLabel. 1 QLineEdit. 1 QSpinBox avec px en suffix. 3 QRadioButton dans un QGroupBox avec layout vertical. 8