SN IR 1 2014-2015 Développement logiciel Programmation Objet Tutoriel QT Date : février 2015 Version : 3.2 Référence : Projet Alarme Domestique ~ TD n 4 ~ 1. Objectif Découverte de la programmation sous Qt Prise en main de l'environnement de développement Fabrication d'une première boîte de dialogue Notion de signal et slot utilisation d'un timer. 2. Conditions de réalisation Ressources utilisées : Un PC sous Windows ou sous Linux Modelio, La suite open Office Qt-creator
3. Création d'un projet Après avoir lancé Qt creator, choisir dans le menu fichier l'option nouveau fichier ou projet. Choisir ensuite un Projet Qt C++ de type Application graphique Qt comme le montre la figure. Ce projet se nomme AlarmeDomestique, il est placé sur le disque de travail dans votre dossier Projet_Qt. Dans un premier temps, réaliser la classe Clavier dont le parent sera de type QMainWindow. (relation d'héritage) L'EDI fabrique les fichiers suivants : alarmedomestique.pro clavier.h clavier.ui clavier.cpp main.cpp Contient la structure du projet En-tête de la classe Clavier Contient l'interface utilisateur Code de la classe Clavier Programme principal #include <QtGui/QApplication> #include "clavier.h" int main(int argc, char *argv[]) QApplication a(argc, argv); Clavier leclavier; leclavier.show(); return a.exec(); Le fichier main.cpp est terminé il déclare une instance de la classe Clavier et affiche l'interface utilisateur associée puis exécute l'application. Un double clic sur le fichier permet de l'éditer. Le fichier alarmedomestique.pro est fait automatiquement pour l'instant il n'est pas à modifier. Le fichier clavier.ui lance la partie design et permet de fabriquer l'interface graphique. Clavier et Détecteur IHM QT Page 2 sur 6
4. Réalisation de l'interface utilisateur (l'aspect graphique) L'interface est composée de 12 pushbutton et de 2 checkbox comme le montre la figure : Chaque widget fait l'objet d'un glissé vers la grille de construction de l'ihm. Ils sont renommés dans la partie propriété de l'écran Les noms sont choisis de manière cohérente par rapport à l'application. Le fait de garder le type d'objet en préfixe permet de savoir sur quel objet le programmeur travaille. Toujours dans la zone de propriété pour les deux checkbox, retirez la possibilité que l'utilisateur puisse cocher la case (ici nous souhaitons, juste visualiser l'état de la centrale d'alarme). Après exécution, vous obtenez la boîte de dialogue suivante : Pour modifier le titre de la fenêtre, après avoir sélectionné la grille représentant l'interface utilisateur, dans les propriétés, il est possible de changer le titre Clavier et Détecteur IHM QT Page 3 sur 6
5. Association des boutons aux slots Pour que chaque bouton réagisse, il est nécessaire d'associer un signal issu de ce bouton à un slot. En cliquant avec le bouton droit de la souris et sur le bouton «Marche» de l'interface et en sélectionnant l'option aller au slot... la boîte de dialogue suivante s'affiche : Pour notre application, trois signaux vont nous intéresser : clicked() pressed() released() Lorsque le bouton est simplement actionné Lorsque le bouton est enfoncé Lorsque le bouton est relâché Lorsque est sélectionné clicked() et que vous validez avec «OK» la méthode suivante correspondant au slot est créé dans la classe clavier. Reste maintenant à programmer le contenu de la méthode pour réagir à l'appui sur le bouton «Marche» Dans le fichier clavier.cpp Dans le fichier clavier.h void Clavier::on_pushButton_Marche_clicked() private slots: void on_pushbutton_marche_clicked(); Par exemple : Aprés avoir inclus le fichier <QMessageBox>, ajouter dans le corps de la méthode les éléments suivants : QMessageBox uneboitemessage ; uneboitemessage.settext ("J'ai appuyé sur Marche"); uneboitemessage.exec (); Compilez et exécutez le programme, après appui sur le bouton «Marche», la boîte de message apparaît. En procédant de manière identique c'est à dire association du signal clicked() pour la touche 1 au slot correspondant et en complétant le code par les lignes suivantes, il est possible d'obtenir le texte de la touche : void Clavier::on_pushButton_1_clicked() QString texte = ui->pushbutton_1->text (); QMessageBox uneboitemessage; uneboitemessage.settext ("J'ai appuyé sur la touche " + texte); uneboitemessage.exec (); ui est un pointeur sur l'interface utilisateur, il donne accès aux différents widgets présents sur la vue. Ici, pushbutton_1 est un pointeur sur QAbstractButton qui offre toutes sortes de méthode pour agir sur notre bouton notamment dans le cas présent la récupération du texte présent sur le bouton. Clavier et Détecteur IHM QT Page 4 sur 6
6. Mise à jour des cases à cocher Toujours en utilisant le pointeur ui, il est possible d'accéder aux autres éléments de la vue par exemple les cases à cocher. Ainsi ui->checkbox_ledrouge->checkstate () donne l'état de la led Rouge, elle peut prendre les valeurs Qt::Checked ou Qt::Unchecked. De même, la méthode ui->checkbox_ledrouge->setcheckstate(...) avec la valeur du paramètre adapter permet de cocher ou décocher la case. En utilisant les informations du paragraphe 5 concernant le fonctionnement des boutons, ajoutez au slot associé à l'appui sur le bouton «Arrêt» le fait que la led rouge s'allume ou s éteigne à chaque nouvel appui en fonction de l'état précédent. Dans un deuxième temps, compléter le code pour que la led verte et la led rouge s'allument et s éteignent alternativement en appuyant sur le bouton «Arrêt». Quelle méthode de la classe Clavier est appropriée pour initialiser la led verte avec la valeur cocher au départ? Dans la section privée de déclaration de la classe Clavier, ajoutez un pointeur sur un objet QTimer nommé timerled. private: Ajouter également la ligne : Ui::Clavier *ui; QTimer *timerled ; #include <QTimer> Maintenant dans le constructeur de la classe Clavier, le pointeur timerled doit être initialisé et le signal timeout() (temps écoulé) issu de cet objet doit être connecté au slot de traitement Clavier::Clavier(QWidget *parent) : QMainWindow(parent), ui(new Ui::Clavier) ui->setupui(this); ui->checkbox_ledverte->setcheckstate (Qt::Checked); timerled = new QTimer(this); connect (timerled,signal(timeout()),this, SLOT (on_fintimerled ())); Il est nécessaire de prévoir dans le destructeur la libération de la mémoire obtenue pour le timerled. Il faut également ajouter une méthode void on_fintimerled() dans la classe Clavier qui servira de slot et réagira donc au signal timeout() du timerled. Dans la déclaration de la classe clavier, au niveau de la section on complète avec : private slots: void on_pushbutton_arret_clicked(); void on_pushbutton_1_clicked(); void on_pushbutton_marche_clicked(); void on_fintimerled(); Dans le corps de la méthode void Clavier::on_FinTimerLed() reste plus qu'a ajouté le traitement nécessaire pour inverser l'état de la led. void Clavier::on_FinTimerLed() if(ui->checkbox_ledverte->checkstate () == Qt::Checked) ui->checkbox_ledverte->setcheckstate (Qt::Unchecked); else ui->checkbox_ledverte->setcheckstate (Qt::Checked); Un autre bouton peut-être utilisé pour arrêter le QTimer et ainsi suspendre le clignotement en utilisant l'appel de la méthode : timerled->stop() ; Clavier et Détecteur IHM QT Page 5 sur 6
7. Affichage d'une nouvelle boîte de dialogue (le détecteur) Avec le bouton droit de la souris sur la racine dans l'explorateur de projet, sélectionnez l'option Ajouter nouveau... pour faire apparaître la fenêtre suivante et sélectionner une Classe d'interface graphique Qt Designer. Dans notre cas le choix se porte ensuite sur une boîte de dialogue sans bouton. Le nom de la classe après avoir appuyé sur suivant sera Detecteur. Le projet est maintenant complété par les fichiers permettant la gestion du détecteur. La vue graphique peut être complétée par un nouveau bouton «Présence détectée» Il est nécessaire de nommer correctement le bouton : Pour l'exercice, déclarez dans la classe Clavier un nouvel attribut nommé ledetecteur un pointeur sur la classe Detecteur. Ensuite, la touche 2 du clavier va faire apparaître un détecteur et la touche 3 le faire disparaître. Après avoir associé le signal clicked() de ces 2 touches aux slots correspondants, instanciez dynamiquement ledetecteur et faite apparaître cette nouvelle boîte de dialogue à l'aide d'une des deux techniques présentées ci-après. Comparez le fonctionnement de la méthode show() avec la méthode exec(). void Clavier::on_pushButton_2_clicked() ledetecteur = new Detecteur ; ledetecteur->show(); void Clavier::on_pushButton_2_clicked() ledetecteur = new Detecteur ; ledetecteur->exec(); Dans le 1er cas : Après avoir ajouté les lignes suivantes que constatez-vous lorsque vous appuyez sur la touche 3? Que constatez-vous si vous appuyez plusieurs fois sur la touche 3? Comment peut-on résoudre le problème? void Clavier::on_pushButton_3_clicked() delete ledetecteur ; Quelle autre méthode permet de cacher une boîte de dialogue? Que ce passe t'il dans le cas de la méthode exec()? Proposez une solution pour éviter de saturer la mémoire. Pour modifier le titre de la boîte de dialogue, ajoutez dans le constructeur de la classe Detecteur la ligne : setwindowtitle("detecteur"); Clavier et Détecteur IHM QT Page 6 sur 6