URL: https://linuxfr.org/news/projet-qt5-lecteur-de-musique Title: Projet Qt5 : lecteur de musique Authors: _jordan_ Nils Ratusznik, baud123, Nÿco, gst, Florent Zara et Davy Defaud Date: 2012年12月27日T13:22:37+01:00 License: CC By-SA Tags: Score: 44 | ------|------ Comme vous avez pu le voir dans [cette dépêche](http://linuxfr.org/news/sortie-de-qt-5-0), le _framework_ C++ Qt5 est maintenant sorti. Cette dépêche revient sur certaines bases de la programmation C++/Qt, ainsi que ses évolutions à travers un cas concret : la création d’un lecteur de musique.| ---- [La dépêche sur la sortie de Qt5](https://linuxfr.org/news/sortie-de-qt-5-0) [Le dépot GIT (github)](https://github.com/skywodd/mandarine) [Le site de Qt](https://qt-project.org/) [Fonctionnalités de Qt](https://qt-project.org/wiki/Qt-5Features) ---- Un projet Qt est divisé en 3 parties : le code principal du programme, la partie graphique et une couche faisant le lien entre les deux. En fait, c'est une implémentation du MVC (Modèle, Vue, Contrôleur) plus proche du Modèle/Vue. # Projet avec Qt # Qt est une bibliothèque très importante avec beaucoup de fonctionnalités. En général, on utilise Qt Creator qui est l'environnement de développement dédié, Qt Designer servira pour la partie graphique. Je ne développerai pas cette partie, tout est affaire de QWidget que l'on place, comme avec tout éditeur visuel. Sachez aussi qu'il est possible de coder via QML (Qt Markup Language) qui est un langage adapté, proche du XML, Javascript, CSS à la sauce moderne -> voir [cette dépêche](http://linuxfr.org/users/gof/journaux/qml-le-futur-des-interfaces-graphiques). Enfin, Qt étant multi-plateforme, le style visuel de chaque widget s'adapte à son environnement et on peut aussi l'adapter grâce à des styles semblables aux CSS. ## Le code principal ## Le code principal ressemble à du C++, mais étant donné qu'on utilise souvent un nombre important de fonctions Qt, on a plus l'impression de faire un nouveau langage. Après, cela dépend de l'application. ### Signaux et slots ### Dans Qt, pour communiquer, tout est à base de signaux et slots. Cela permet de faire de la programmation événementielle. L'idée est d'envoyer un signal quand un évènement vient de se passer (ex : une valeur modifiée). Chaque objet qui veut recevoir un signal doit posséder un slot compatible. Ensuite, on fait un `connect` et le tour est joué. C'est tout simplement une implémentation du pattern observateur/observable. Déclaration : ```c++ //Création d'une classe foo implémentant signaux et slots pour gérer la modification d'une valeur class Foo: public QObject { Q_OBJECT public : Foo(); int value() const {return val;} public slots : void setValue(int); //A un corps signals : void valueChanged(int); //N'a pas de corps private : int val; } ``` Lancement d'un signal : ```c++ void MonQObject::setValue(int v) { if(v!=val){ val=v; emit valueChanged(v); //On émet le changement de valeur //Un autre objet pourra ainsi agir après l’émission } } ``` Connexion : ```c++ Foo a,b; connect(&a, &Foo::valueChanged, &b, &Foo::setValue); ``` Plus d'informations et exemples : http://web.njit.edu/all_topics/Prog_Lang_Docs/html/qt/signalsandslots.html (en Qt3) et pour Qt5 : http://qt-project.org/doc/qt-5.0/qtcore/signalsandslots.html ### L'interface programme/graphique ### Cette partie fait le lien entre le code principal du programme et la partie graphique. Chaque classe hérite en public de QWidget et en privé de la classe graphique correspondante (créée avec le designer) ```Ui::Maclasse```. Les seuls attributs sont les informations nécessaires à l'affichage. Par exemple : `bool isRunning` pour mon player sert à afficher l’icône play ou pause selon l'état du player. On crée ensuite des slots correspondant aux boutons de l'interface graphique pour faire les modifications graphiques nécessaires. On émet les signaux correspondant à nos slots. Exemple : j'ai un slot setPlayPause, je regarde l'état isRunning, je met à jour l’icône play/pause et j’émets le signal pause. Les `connect` entre interface graphique et slots sont faits dans le constructeur. ## L'environnement de développement ## ### Qt Creator ### Qt creator offre tout ce que l'on peut attendre d'un IDE moderne, il offre des connexions avec des gestionnaires de version, des fonctions de refactorisation, l'intégration d'un débogueur et d'un analyseur de code, un clone de Vim anecdotique mais appréciable, et une gestion de la documentation très intéressante. ### Documentation ### D'ailleurs, je veux parler très rapidement de la documentation, car c'est un véritable bonheur. Vous n'avez que l’embarras du choix : elle est disponible de manière complète dans Qt Creator dans un onglet séparé, elle s'affiche à droite de l'écran par l'appui de F1 au survol du code, elle est disponible dans une version web sur le site de digia et dans un logiciel dédié : Qt designer. Qt designer est en fait un navigateur web sur la doc que vous possédez en local et comme il a spécialement été adapté pour celle-ci, il offre un confort de recherche accru, tout en proposant toutes les fonctionnalités pratiques de votre navigateur web préféré. ### Traduction ### Qt et Qt creator ont un outil de traduction pratique à utiliser, il suffit d'entourer les chaînes de caractères traduisibles dans un programme par un appel à la fonction `tr()` et un fichier de traduction sera généré. # Les apports de Qt5 # Comme vu dans la [dépêche de sa sortie](http://linuxfr.org/news/sortie-de-qt-5-0), Qt5 apporte beaucoup de choses. Dans le cadre d'un lecteur audio, il y a toute une partie qui m'a été très utile : QMultimedia. Le QMedia player se dote maintenant d'une bonne gestion des listes de lecture et d'objets pour manipuler directement des fichiers audio et vidéo. Bien entendu, toutes les fonctions de base sont là : lecture, pause, changement de volume, changement de vitesse, mode de lecture ou autre. On n'est plus obligé de passer par la bibliothèque phonon. En outre, le confort de c++ 2011 est là donc on peut allègrement employer les lambda tant qu'on possède un compilateur adapté. Enfin, Qt5 apporte la vérification des signaux et slots à la compilation et des gains de performance. # Mon projet : Mandarine # ## Cahier des charges ## Mandarine est un projet d'école, c'est censé être une copie de Clémentine (lecteur de musique Linux, Mac OS X et Windows). Comme tout bon lecteur de musique il doit gérer les fonctionnalités suivantes : * lecture de fichiers ou flux audio ; * gestion de listes de lectures (playlist) ; * gestion de bibliothèques ; * affichage de jaquettes et d'informations sur les artistes et albums (intégration de Wikipédia). ## Détail du projet ## ### Le GUI ### L'interface graphique se veut simple, aucunement révolutionnaire. La seule fantaisie est peut être le gestionnaire de bibliothèque qui est un dock qu'on peut détacher dans une fenêtre séparée. La lecture de flux audio utilise plusieurs classes, voici l'exemple d'une d'elles. ### PlayerControls ### (gestion des boutons de lecture). Ceci est typiquement une classe qui sert d'interface programme/code. On n’interagit qu'avec les boutons, on modifie les icônes et on renvoie les signaux intéressants. Fonctionnalités : * lecture / pause (même bouton, changement dynamique d’icône) ; * stop ; * morceau suivant et précédent ; * possibilité de désactivation des contrôles en lot si besoin ; * bouton « vitesse de lecture » : menu contextuel ; * bouton « mode de lecture » : menu contextuel (séquentielle, en boucle, aléatoire : case à cocher). Membres : * boolean isplaying = false * int speedLevel = SPEED_NORMAL * int playMode = SEQUENTIAL { SEQUENTIAL, LOOP, RANDOM } * int mode = BEGIN { BEGIN, RUNNING, ENDING } Signaux : * play() / pause() / stop() * fastForward(level) * next() / previous() * playModeChanged(playMode) * modeChanged(mode) * speedChanged() Slots : * setStatus(bool enabled) //(activer ou désactiver tous les boutons) * setMode(mode) * setPlayMode(playMode) * reset() //setStatus(disable), setMode(SEQUENTIAL), setPlayMode(BEGIN) [playercontrol.h](https://github.com/skywodd/mandarine/blob/master/playercontrols.h) [playercontrol.cpp](https://github.com/skywodd/mandarine/blob/master/playercontrols.cpp) Cette partie s'adresse à deux types de personnes : le débutant en programmation et quelqu'un qui n'aurait jamais vraiment fait ce genre de choses, le c++ n'est pas un langage voué à mourir de sitôt, on peut facilement faire des programmes dignes du 21^ème siècle. # La suite du projet # En toute logique, tout s’arrête là, aucune mise à jour n'est à prévoir. Ses différents atouts : simplicité, légèreté, modernité vous plairont peut être, j'aiderai quiconque voulant le reprendre pour un faire un vrai petit logiciel sympa.