Cours de QtCreator
Cours de QtCreator avec exercices
...
1) Création d’un projet
En utilisant l’icône QtCreator, lancez l’application et créez un projet de type GUI.
Une succession d’écrans vous permettant alors de créer un projet.
Dans un premier temps, il suffit de choisir un nom de projet et de choisir un répertoire de travail. Attention, ne mettez qu’un seul projet par répertoire car un projet se compose d’un ensemble de fichiers et il est important d’éviter les conflits.
Il est important ensuite de choisir les modèles Qt à inclure dans votre projet. Par défaut seul les modules minimaux sont inclus et en particulier le module permettant de gérer les interfaces graphiques.
Le dernier écran vous permet de modifier d’une part le nom de la classe principale et par conséquent les noms des fichiers C++ correspondant. Par défaut :
- mainwindow.cpp
- mainwindow.h
Notons la présence d’un fichier mainwindow.ui qui correspond au fichier de l’interface graphique c’est-à-dire permettant au générateur d’interface de fonctionner.s
2) Structure d’un projet
Le projet se compose de 5 fichiers :
- les 2 fichiers C++ dont les noms correspondent au projet
- un fichier main.cpp qui correspond au programme principal.
- Le fichier mainwindow.ui qui correspond à l’interface graphique.
- Le fichier projet Qt nommé ici essai_demonstration.
Le fichier main.cpp
On n’a vraiment besoin de le modifier que si on souhaite modifier la fenêtre de démarrage ou bien inclure de nouvelles librairies Qt.
Les fichiers mainwindow.cpp et mainwindow.h
Ces fichiers devront être souvent modifiés pendant la conception de l’interface graphique pour ajouter de nouveau slot ou signaux et ainsi faire communiquer les objets de l’interface.
3) Le générateur d’interface
Un double click sur mainwindow.gui lance automatique le générateur d’interface.
3.1. Création d’un bouton « Quitter »
Etape 1. Création d’un bouton dans la fenêtre.
Dans la section Buttons, par click à la souris, insérer un bouton sur la fenêtre, par exemple à bas à droite.
L’inspecteur d’objet affiche alors les caractéristiques de l’objet bouton qui vient d’être crée.
Deux propriétés sont importantes :
La propriété objectName correspond au nom C++ de l’instance bouton qui vient d’être crée. Cette propriété est dans la section QObject.
La propriété Text dans la section QAbstractButton qui correspond au texte affiché sur le bouton.
Modifions cette propriété en « Quitter ». Le bouton ressemble alors à ce qui suit :
Etape 2. Attacher du code sur l’événement click sur le bouton.
Pour cela dans le fichier mainwindow.h créer une nouvelle section nommée « Private Slots » et définir une procédure nommée par exemple « BoutonQuitter ».
Il faut inclure dans ce fichier :
- Le corps de la méthode BoutonQuitter
- Une connexion entre le signal ou événement « click » et la méthode BoutonQuitter ;
La méthode « BoutonQuitter » contient un simple appel à la méthode « close » de la fenêtre.
void MainWindow::BoutonQuitter()
{
this->close();
}
Le lien entre l’événement « Click » et la méthode se fait par la méthode Connect :
connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(BoutonQuitter()));
Celle-ci ce compose de 3 parties principales :
- Le premier paramètre (ui->pushButton) fait référence à l’object graphique ;
- Le deuxième SIGNAL(clicked()) fait référence à l’événement concerné (ici « click ») ;
- Le quatrième crée la connexion entre l’objet graphique et la procédure (en Qt le lien s’appelle un slot).
Etape 3. Vérification.
Après compilation et en lançant directement le code à partir de QtCreator on obtient le résultat suivant avec la fermeture de la fenêtre sur l’événement click du bouton.
En examinant le dossier de travail, on retrouve les différents fichier du projet ainsi qu’un fichier nommé « essai_demonstration.app » sous MacIntosh ou « essai_demonstration.exe » sous Windows.
Le double click sur le fichier lance automatique l’application. Attention sous windows, il est nécessaire que votre variable d’environnement PATH contienne un lien vers les fichiers .dll de Qt. Si ce n’est pas le cas, penser à cliquer sur le poste de travail et à modifier vos variables d’environnement.
3.2. Afficher des messages sur la fenêtre.
Créez une fenêtre avec un « Lineedit » et un « textEdit » séparé par un bouton intitulé « Lire » comme indiqué sur la copie d’écran ci-dessous.
Comme précédemment, déclarer une nouvelle procedure dans le fichier mainwindow.h :
Le fichier mainwindow.cpp doit être modifié comme suit :
En venant du C++ standard, il faut prendre soin d’utiliser les types spéciaux Qt dont en particulier le type QString et non pas le type string classique.
Le résultat à l’exécution est le suivant :
On peut constater que le texte du LineEdit est bien ajouté au fur et à mesure dans la zone de type TextEdit. Nous avons sur cet exemple mis en évidence la différence entre une zone de type LineEdit et une zone de type TextEdit.
3.3. Utilisation des barres de progression.
Ajoutez sur la fenêtre une barre de progression qui se trouve dans la section « Display Widgets ».
Ajouter 3 boutons afin d’obtenir une fenêtre comme celle-ci :
Comme précédemment, modifiez le fichier mainwindow.h :
...
Installation de QTcreator
Toutes les informations se trouvent ici: Il va falloir répondre à quelques questions et éventuellement créer un compte (il existe un bouton ’skip’). Ensuite lancez l’installateur qui va lui même télécharger plein de choses (cela va prendre du temps). Attention, lorsque l’installateur vous demande à quel endroit installer QTcreator, choisissez bien car vous ne pourrez pas le déplacer facilement. Pendant que tout cela s’installe commencer à lire et réfléchir au sujet
Développement d’une application simple: Chronomètre
Votre but est de développer une application représentant un chronomètre simple. Un chronomètre est utilisépour mesurer une durée. Il possède un bouton pour démarrer et arrêter le compteur et un autre pour mettre en pause le défilement du temps sur l’affichage (aussi connu sous le nom de “split”, oùle compteur continue de garder le temps alors que l’affichage est arrêtésur le temps lors de l’appui sur pause. Cela sert, par exemple à mesurer le temps de chaque tour lors d’une course). Lorsque le chronomètre a étéarrêté, l’affichage reste figésur le temps lors de l’appuie sur le bouton. Le bouton start/stop sert alors à remettre l’affichage à 0.
Une squelette simple d’implémentation sur Qt vous est fourni sur ma page web. Vous pouvez modifier le code comme bon vous semble mais le fonctionnement doit être celui décrit ci dessus. Pour l’importer, le plus simple est de créer un nouveau projet (choisissez bien son emplacement, il ne sera pas facilement déplaçable). Choisissez une application Qt Widgets puis décochez generate forai. Vous choisirez comme cible de compilation la version de Qt la plus récente pour votre architecture (5.8 sur mon PC). Ensuite, supprimez de manière permante les fichers générés et remplacez les par ceux fournis sur mon site web. Vérifiez que le code compile et se lance.
1Je ne travaille en recherche ni dans les interfaces graphiques ni avec Qt, comprenez donc que le but n’est ni de devenir pro de Qt ni de faire de jolies interfaces
Figure 1: Différentes vues d’une application chronomètre simple
Version 1
Dans la première version je vous laisse implémenter le comportement simple de l’application chronomètre par vous même. Vous avez le droit de modifier tous les fichiers, de rajouter des attributs, des méthodes, etc à la classe existante. Verifiez bien que vous avez le comportement souhaité, que vous me ferez valider.
Version 2
Qt intègre un éditeur de state machine sous le format SCXML. Pour activer le plugin, encore en incubation, allez dans Help -j About Plugins et cochez ScxmlEditor dans la partie Modelling.
Votre mission pour cette version 2, créer un nouveau projet, repartir du squelette vide et définir une ma¬chine à état permettant de définir le comportement souhaitéde l’interface. Ceci se fera en deux temps: Premièrement, ne vous préoccupez pas du code et définissez uniquement la machine à état. Une fois que vous pensez que c’est correct, faites moi valider.
Ensuite, vous lierez cette machine à état à du comportement dans votre code. Pour ce faire, voici la marche à suivre:
- assurez vous que la machine a état soit correctement compilée en ajoutant scxml à la ligne QT += core gui widgets du fichier “.pro”;
- ajoutez un attribut de type “leNomDeVotreStateMachine” à la classe StopWatch. Pour ce faire, ra¬joutez un include ayant le même nom que votre fichier scxml mais finissant par .h (la complétion est votre amie). Si vous ne trouvez pas le fichier correspondant, alors la state machine n’est pas com¬pilée correctement. Enfin vous pouvez appeler la méthode start() sur l’objet de type leNomDe¬VotreStateMachine que vous venez de définir.
- connectez des “bouts de code” à l’évolution de la machine à état. Pour ce faire vous avez deux primitives:
– objetFSM.connectToEvent(
QStringLiteral("nomEvenementDansFSM"),
this,
&StopWatchFSM::uneFonctionMembreDeLaClasseStopWatchFSM
);
Ici le code de la fonction membre sera appelée dans le contexte de this à chaque fois que l’évènement “nomEvenementDansFSM” survient (occurs).
– objetFSM.connectToState(
QStringLiteral("nomStateDansFSM"),
this,
&StopWatchFSM::uneFonctionMembreDeLaClasseStopWatchFSM
);
Ici le code de la fonction membre sera appelée dans le contexte de this à chaque fois que la machine à état entre dans l’état “nomStateDansFSM”.
à noter que vous pouvez également connecter les événements qui sont déclenchés par le clic sur un bouton en événement à destination de votre state machine:
connect(
adresseDuBouton,
&QAbstractButton::clicked,
[this] { objetFSM.submitEvent("startStop");}
);
Encore une fois vous pouvez (devez) ajouter ce que vous voulez au code existant du moment qu’il a le comportement souhaité.
Version 2: Mealy ou Moore ?
Réfléchissez. Avez vous fait une machine de Mealy, de Moore ou un mixte des deux ? Faites une deuxième version distincte de votre state machine afin d’avoir une version de Mealy et une de Moore. Que pouvez vous en dire ?
Version 3
Vous allez ajouter du comportement à la version 2. Il s’agit ici d’ajouter un troisième bouton “mode”. Ce bouton permet d’afficher l’heure ou la date pendant 1 seconde. Au premier appuie sur le bouton, l’affichage devra montrer l’heure courante. Au bout d’une seconde, si le bouton n’a pas étéappuyéà nouveau, le chronomètre retourne dans l’état oùil était. Si le bouton est appuyéà nouveau avant 1 seconde, l’affichage montrera la date. De même, si aucun bouton n’est appuyépendant 1 seconde on retourne au comportement initial, sinon on remontre l’heure courante. Le fonctionnement décrit sera actif peu importe l’état dans lequel se trouve le chronomètre (arrêté, démarré, en pause, etc).
Version 4
Vous allez ajouter du comportement à la version 2 (peu importe que celui-ci soit très pertinent, c’est pour l’exemple). Il s’agit ici d’ajouter un troisième bouton et 5 labels. Ce bouton permettra de gérer les nouveaux labels. Le fonctionnement suivant sera actif peu importe l’état dans lequel se trouve le chronomètre (arrêté, démarré, en pause, etc). Lors d’un appuie sur le bouton, le temps courant sera stockédans le prochain label libre, ou s’il n’y en a plus, dans le premier à avoir étéutilisé. Si le bouton est appuyédeux fois de suite dans un intervalle de 1 seconde alors tous les labels sont réinitialisés.
Bien sûr l’implémentation utilisera la machine à état et mettra en œuvre les constructions vues en cours.
Version 5
Vous allez repartir du squelette de code qui vous a étéfourni initialement. Maintenant que vous avez décrit la machine à état (de la version 2), vous allez l’implémenter manuellement. Essayez de structurer votre code au mieux !
Qu’en est-il si vous deviez implémenter manuellement la version 3 ? La 4 ?