Programmation Qt/Version imprimable

Un livre de Wikilivres.
Sauter à la navigation Sauter à la recherche
Nuvola-inspired File Icons for MediaWiki-fileicon-ps.png

Ceci est la version imprimable de Programmation Qt.

  • Si vous imprimez cette page, choisissez « Aperçu avant impression » dans votre navigateur, ou cliquez sur le lien Version imprimable dans la boîte à outils, vous verrez cette page sans ce message, ni éléments de navigation sur la gauche ou en haut.
  • Cliquez sur Rafraîchir cette page pour obtenir la dernière version du wikilivre.
  • Pour plus d'informations sur les version imprimables, y compris la manière d'obtenir une version PDF, vous pouvez lire l'article Versions imprimables.


Programmation Qt

Une version à jour et éditable de ce livre est disponible sur Wikilivres,
une bibliothèque de livres pédagogiques, à l'URL :
https://fr.wikibooks.org/wiki/Programmation_Qt

Vous avez la permission de copier, distribuer et/ou modifier ce document selon les termes de la Licence de documentation libre GNU, version 1.2 ou plus récente publiée par la Free Software Foundation ; sans sections inaltérables, sans texte de première page de couverture et sans Texte de dernière page de couverture. Une copie de cette licence est incluse dans l'annexe nommée « Licence de documentation libre GNU ».

Sections

Avant-propos

Pendant l'apprentissage de ce livre, nous considérerons que vous avez des bases en C++ et en programmation orientée objet. N'hésitez pas à aller voir Programmation C++ et Programmation/Programmation orientée objet.


Introduction

Qtcreator-overview.png

Introduction[modifier | modifier le wikicode]

Qt est un framework initialement prévu pour faciliter la création d'interfaces graphiques pour le langage de programmation C++. Au fil du temps et des nouveaux apports aux bibliothèques de Qt, ce framework s'est étendu progressivement au delà des interfaces graphiques pour fournir une bibliothèques de composants facilitant l'utilisation du langage C++ (sockets, fichiers, structure de données, threads, synchronisation, ...), allant jusqu'à permettre la portabilité du code source à différentes plateformes. La portabilité des applications n'utilisant que des composants Qt se fait par simple recompilation du code source. Les environnements supportés sont les Unix (dont Linux) qui utilisent le système graphique X Window System, Windows et Mac OS X.

Le fait d'être une bibliothèque logicielle multiplate-forme attire un grand nombre de personnes qui ont donc l'occasion de diffuser leurs programmes sur les principaux OS existants. Qt est notamment connu pour être la bibliothèque sur laquelle repose l'environnement graphique KDE, l'un des environnements de bureau les plus utilisés dans le monde Linux.

Qt fut distribué par Trolltech sous la licence GPL. En 2008, Nokia rachète Trolltech, et en 2009 Nokia décide de changer la licence pour LGPL, permettant la création de logiciel propriétaire sans obtenir une autorisation ou licence de revente de Qt.

Voir l'article sur wikipédia pour plus de détails sur l'histoire de Qt.

Nous allons étudier quelques bibliothèques Qt, dans sa version 4, en utilisant le langage C++. Qt est disponible sous licence GPL (cf Licence publique générale GNU) pour les systèmes GNU/Linux, Mac et Windows.

Notez également que l'on peut coder avec Qt en Python ou en Java (bien que le projet ai été abandonné quand Nokia a racheté Qt).

Installation[modifier | modifier le wikicode]

Vous pouvez télécharger Qt sur le site de Nokia.

La page de téléchargement propose différents logiciels :

QtSDK
QtSDK est une version binaire incluant les bibliothèques Qt, les outils de développement Qt, le logiciel Qt Creator, Qt mobility et simulateurs pour développer sur téléphone mobile Symbian et Nokia N9. En plus de pouvoir développer des applications pour ordinateurs de bureau, il permet dont de développer des applications pour téléphones mobiles.
QtSDK est disponible pour Windows, Linux, Mac OS X, en 32 bits, et Linux et Mac OS X en 64 bits. Cela signifie que pour développer des applications pour Windows en 64 bits, il faudra recompiler les fichiers sources (voir les codes sources téléchargeables ci-dessous et la page Développer pour Windows 64 bits).
QtDSK utilise un compilateur C++ externe. Sous Windows, il peut s'agir de Microsoft Visual C++, ou bien de GNU MinGW.
Qt Libraries
Code source des bibliothèques de Qt incluant les outils de développement en ligne de commande. Il faut sélectionner le système d'exploitation et le compilateur utilisé pour Windows.
Qt Creator
Qt Creator est un IDE permettant de créer facilement des interfaces graphiques et de gérer des projets. Il supporte également git pour gérer les fichiers sources placés en gestion de configuration.

QtSDK permet une installation automatique sans recompiler les sources de Qt.

La compilation des sources Qt est nécessaire pour développer des applications Windows 64 bits (voir Développer pour Windows 64 bits).

Les programmes installés[modifier | modifier le wikicode]

Qt a installé différents logiciels qui vous seront utiles :

Qt Examples and Demos
Ce logiciel est juste une démonstration des possibilités de Qt. Il est là juste pour présenter Qt.
Qt Assistant
Qt Assistant est la documentation de Qt en hors-ligne. Elle est très complète. Par contre, son défaut est qu'elle est en anglais comme pratiquement toutes les documentations pour développeurs.
Qt Linguist
C'est une application pour traduire vos programmes. Celui-ci simplifie la tâche du programmeur puisqu'il traduit le programme en plusieurs langues.
Qt Designer
Cette application s'avérera utile quand vous saurez l'utiliser. Elle vous permettra de personnaliser vos IHM. Mais une fenêtre se code et il est conseillé de savoir coder une fenêtre avant d'utiliser Qt Designer.


Développer pour Windows 64 bits

Qt ne propose qu'une version 32 bits du QtSDK pour Windows. Il est cependant possible de compiler les sources de Qt avec un compilateur C++ 64 bits pour développer des applications pour Windows 64 bits.

Ce chapitre explique en détail les étapes pour créer un environnement de développement d'applications pour Windows 64 bits. Si vous ne développez pas d'applications pour Windows 64 bits, vous pouvez passer au chapitre suivant.

Installations préparatoires[modifier | modifier le wikicode]

Windows SDK[modifier | modifier le wikicode]

Si vous utilisez Windows XP, Windows Vista ou Windows 7, et que vous désirez que les composants graphiques de vos applications adoptent la même apparence que celles des autres applications, il est nécessaire de télécharger et installer Windows SDK. Celui-ci est disponible ici : https://www.microsoft.com/download/en/details.aspx?displaylang=en&id=8279

Installez-le dans le répertoire proposé par défaut (en général, pour la version 7.1 il s'agit de C:\Program Files\Microsoft SDKs\Windows\v7.1).

Compilateur C++[modifier | modifier le wikicode]

Il faut ensuite installer le compilateur C++ pour Windows 64 bits qui servira à compiler Qt et les applications par la suite.

Vous pouvez utiliser un compilateur C++ gratuit :

Par convention, installez-les dans les répertoires C:\MinGW64 et C:\Msys64, respectivement. Vous pouvez utiliser d'autres répertoires ou lecteur de disque.

Open SSL[modifier | modifier le wikicode]

Si vous envisagez d'utiliser SSL avec Qt, installez également Open SSL pour Windows. La version 0.9.8 pour x64 est disponible ici : http://code.google.com/p/openssl-for-windows/downloads/detail?name=openssl-0.9.8k_X64.zip&can=2&q=

Installez-le dans C:\OpenSSL-Win64

Sources de Qt[modifier | modifier le wikicode]

Téléchargez les sources de Qt Libraries et Qt Creator sur http://qt.nokia.com/downloads, et installez-les dans les répertoires suivants :

  • Qt Libraries : C:\Qt\vversion (ex: C:\Qt\v4.8.0), sans le répertoire racine de l'archive, c'est-à-dire en ayant directement accès aux répertoires C:\Qt\vversion\bin, C:\Qt\vversion\src ...
  • Qt Creator : C:\Qt\qt-creator-version-src (qt-creator-version-src étant le répertoire racine de l'archive téléchargée).

Compilation[modifier | modifier le wikicode]

Il faut d'abord compiler les bibliothèques de Qt, puis Qt Creator qui les utilisent.

Il est conseillé de créer un batch afin de pouvoir configurer facilement le système et recompiler sans taper plusieurs commandes.

Configuration préparatoire[modifier | modifier le wikicode]

Il faut tout d'abord préparer l'environnement pour la compilation.

rem Ajoute les répertoires où ont été installés le compilateur C++ 64 bits et Windows SDK
rem Pour MinGW :
set "PATH=C:\Msys64\bin;C:\MinGW64\bin;C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\x64;%PATH%"

rem Selon le compilateur utilisé :
rem - pour GCC 4.6 ou plus récent :
set QMAKESPEC=win32-g++-4.6
rem - pour les anciennes version de GCC :
set QMAKESPEC=win32-g++
rem - pour Visual C++ 2010 :
set QMAKESPEC=win32-msvc2010
rem - pour les autres compilateurs, sélectionnez la valeur parmi les sous-répertoires de C:\Qt\v...\mkspecs

Compilation des bibliothèques de Qt[modifier | modifier le wikicode]

  1. Changez le répertoire courant en C:\Qt\vversion
    cd /D C:\Qt\v4.8.0
    
  2. Déterminez ensuite les options pour appeler configure :
    • Les options disponibles sont affichées avec la commande suivante :
      configure -help
      
    • Consultez également la page http://qt-project.org/doc/qt-4.8/configure-options.html
    • Si vous avez installé Open SSL, ajoutez ces options :
      -openssl -I C:\OpenSSL-Win64\include -L C:\OpenSSL-Win64\lib
      
    • Si vous avez installé WindowSDK et désirez avoir des applications ayant une apparence native à Windows :
      • Pour windows XP :
        -qt-style-windowsxp
        
      • Pour windows Vista/7 :
        -native-gestures -qt-style-windowsxp -qt-style-windowsvista
        

Vous pouvez maintenant appeler configure.exe avec les options prédéterminées. Par exemple (ligne découpée sur plusieurs lignes) :

configure -opensource -no-qt3support -no-webkit
    -openssl -I C:\OpenSSL-Win64\include -L C:\OpenSSL-Win64\lib -qt-libtiff -qt-libpng -qt-libmng -qt-libjpeg
    -native-gestures -qt-style-windowsxp -qt-style-windowsvista -fast -platform %QMAKESPEC%
  1. Si la commande configure s'est déroulée sans erreur, le fichier C:\Qt\vversion\Makefile a été créé et la compilation peut commencer :
    • Pour MinGW, utilisez la commande :
      mingw32-make
      
    • Pour Visual C++ :
      nmake
      

Si tout se déroule sans erreur, la compilation peut durer entre 1h et 4h selon la configuration matérielle. La compilation doit avoir généré les programmes suivants :

  • C:\Qt\vversion\bin\assistant.exe
  • C:\Qt\vversion\bin\designer.exe
  • C:\Qt\vversion\bin\linguist.exe
  • ...
  1. Configurer le système pour avoir en permanence Qt et le compilateur C++ dans le PATH :
    1. Clic-droit sur Ordinateur (ou Computer pour Windows en anglais), sélectionnez Propriétés (Properties) ;
    2. Cliquez Paramètres système avancés (Advanced system parameters) ;
    3. Cliquez le bouton Variables d'environnement (Environment variables) ;
    4. Double-cliquez sur la variable PATH dans la partie Variables système ;
    5. Ajoutez les répertoires de Qt et du compilateur (ex : C:\Qt\v4.8.0\bin;C:\MinGW64\bin;C:\Msys64\bin;) devant la valeur actuelle de la variable.
    6. Validez et fermez toutes les fenêtres de dialogue.

Compilation de Qt Creator[modifier | modifier le wikicode]

En gardant la même configuration préparatoire que pour la compilation des bibliothèques de Qt :

  1. Changez le répertoire courant en C:\Qt :
cd /D C:\Qt
  1. Créez un nouveau répertoire QtCreator_version pour la génération de Qt Creator :
md QtCreator_2.4.1
cd QtCreator_2.4.1
  1. Compilez Qt Creator en utilisant les deux commandes suivantes :
rem 1. QMake à partir des sources dans qt-creator-<version>-src
qmake C:\Qt\qt-creator-2.4.1-src

rem 2. Selon le compilateur :
rem    - MinGW :
mingw32-make
rem    - Visual Studio :
nmake

Si tout se déroule sans erreur, la compilation peut durer entre 30 et 80 minutes selon la configuration matérielle. La compilation doit avoir généré le programme C:\Qt\QtCreator_version\bin\qtcreator.exe. Lancez-le et vérifiez qu'aucun message d'erreur ne s'affiche au démarrage (bibliothèque ou module manquant).

Vous pouvez également essayer de créer un programme simple pour tester que l'environnement fonctionne, comme expliqué dans le chapitre suivant.


Un premier programme

Ce chapitre propose de créer un premier programme et de le compiler en utilisant des lignes de commandes, afin de se familiariser rapidement aux mécanismes de compilation de Qt.

Afficher un bouton[modifier | modifier le wikicode]

Ce premier programme crée un bouton et l'affiche dans une fenêtre automatiquement créée par Qt.

Fichier[modifier | modifier le wikicode]

Crystal128-source-cpp.svg HelloWorld.cpp
Programme simple affichant un bouton "Hello world!"
#include <QApplication>
#include <QPushButton>

int main(int argc, char* argv[])
{
    QApplication app(argc, argv);
    QPushButton hello("Hello world!");
    hello.resize(100,30);
    hello.show();
    return app.exec();
}


Compilation[modifier | modifier le wikicode]

Pour compiler le programme :

  1. Ouvrez une fenêtre de commande et assurez vous d'avoir le répertoire du compilateur C++ et celui de Qt dans le PATH :
    • Si vous avez installé la version binaire de QtSDK, lancez la console pour Qt :
      • Sous Windows : Démarrer > Tous les programmes > Qt DSK > Desktop > Qt version for Desktop (compilateur)
    • Sinon, configurez la variable d'environnement PATH puis lancer une console de commandes.
  2. Créez le fichier projet Qt HelloWorld.pro :
qmake -project
  1. Créez le fichier Makefile à partir du fichier projet :
qmake
  1. Construisez le programme en utilisant le compilateur C++ (GCC, Visual C++, MinGW, ...) :
  • Pour GCC :
make
  • Pour Visual C++ :
nmake
  • Pour MinGW :
mingw32-make

Si aucune erreur ne se produit, deux sous-répertoires debug et release ont été créés, et le fichier exécutable a été créé dans l'un d'eux :

  • HelloWorld.exe sous Windows
  • HelloWorld ou a.out sous Unix, Linux

Dans le cas contraire :

  • vérifiez que vous avez bien tapé le code source ci-dessus,
  • vérifiez que vous avez bien utilisé les mêmes noms de fichier,
  • vérifiez que vous avez bien tapé les commandes de compilation,
  • vérifiez l'installation du compilateur C++ et de Qt.

Exécution[modifier | modifier le wikicode]

Au lancement du programme, une fenêtre s'affiche avec un bouton "Hello world!" au centre de celle-ci.

Qt-HelloWorld.png

Code source expliqué[modifier | modifier le wikicode]

Voici le détail du code source expliqué :

En-têtes[modifier | modifier le wikicode]

#include <QApplication>
#include <QPushButton>

Inclusion des fichiers d'en-tête définissant les deux classes utilisées dans le programme.

Fonction principale[modifier | modifier le wikicode]

int main(int argc, char* argv[])
{
    //Code
}

Déclaration standard de la fonction principale lançant l'application.

Notez que l'on peut aussi le trouver écrit comme cela, bien que la version précédente soit plus complète :

int main()
{
    //Code
}

Application Qt[modifier | modifier le wikicode]

    QApplication app(argc, argv);

Création de l'instance unique de la classe QApplication définissant la configuration par défaut des éléments graphiques.

Les arguments de la ligne de commande sont passés au constructeur pour qu'il interprète certaines options. Les options reconnues et traitées sont retirées du tableau au retour du constructeur pour que l'application ne les traitent pas à son tour. Parmi les options traitées :

Nom du programme argv[0]
Le nom du programme (sans extension .exe sous Windows) est utilisé comme nom par défaut pour l'application et comme titre par défaut pour les fenêtres.
-display
(X11 seulement) Sélectionne le display ($DISPLAY par défaut)
-style style
Sélectionne le style utilisé par les éléments de l'interface.

Pour plus de détails sur les options traitées, voir https://qt-project.org/doc/qt-4.7/qapplication.html

Bouton[modifier | modifier le wikicode]

    QPushButton hello("Hello world!");

Création d'un bouton dont le texte "Hello world!" est passé en paramètre du constructeur.

Configuration du bouton[modifier | modifier le wikicode]

    hello.resize(100,30);

Redimensionne le bouton à 100 pixels de largeur et 30 de hauteur.

Afficher[modifier | modifier le wikicode]

    hello.show();

Affiche le bouton dans une fenêtre créée pour le contenir.

Boucle de traitement des évènements[modifier | modifier le wikicode]

    return app.exec();

Lancement l'exécution de la boucle traitant des évènements. La méthode exec() retourne le code de retour du programme.

Fin[modifier | modifier le wikicode]

}

Fin de la fonction principale.


Un second programme[modifier | modifier le wikicode]

Voici un programme très simple qui permettra l'affichage d'une fenêtre, plus précisément la fenêtre principale.

Cette fois-ci le fichier projet sera créé manuellement. Celui-ci définit le modèle de programme à produire (app pour une application), et la liste des fichiers sources et en-têtes.

Crystal128-txt.svg essais.pro
Description du projet Qt
TEMPLATE = app
SOURCES  = main.cpp \
           mainwindow.cpp
HEADERS  = mainwindow.h


Un fichier projet possède une syntaxe similaire à celle des fichiers Makefile. Différentes variables sont définies (=) ou complétées (+=) :

  • TEMPLATE : Modèle d'exécutable à générer (app pour une application autonome, lib pour une bibliothèque ou un plug-in).
  • SOURCES : Listes des fichiers sources (*.cpp) du projet.
  • HEADERS : Listes des fichiers d'en-tête (*.h) du projet.
  • FORMS : Listes des formulaires Qt Designer (*.ui) du projet.
  • DEFINES : Listes des symboles définis lors de la compilation du projet.


Crystal128-source-cpp.svg main.cpp
Fonction principale de lancement de l'application
#include <QApplication>
#include "mainwindow.h"

int main ( int argc, char *argv[] )
{
    QApplication app(argc, argv);
    MainWindow mainWin;
    mainWin.show();
    return app.exec();
}


La fenêtre principale est allouée pour l'exemple sur la pile d'appel. Cependant, dans le cas où plusieurs instances de cette fenêtre (pour ouvrir plusieurs fichiers par exemple) sont créées et ouvertes, ou fermées (dont probablement la première instance créée), il est préférable d'allouer la première instance sur le tas (utiliser un pointer et allouer avec new) et d'utiliser l'option Qt::WA_DeleteOnClose.


Crystal128-source-h.svg mainwindow.h
En-tête pour la classe de la fenêtre principale
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QWidget>

class MainWindow : public QWidget
{
    Q_OBJECT

public:
    MainWindow();

};

#endif


Cette fenêtre dérive de la classe QWidget comme tout objet Qt pour l'interface graphique. Il s'agit avant tout d'un conteneur de widget plutôt que la fenêtre elle-même. La macro Q_OBJECT est utilisée avec toute classe Qt pour définir les informations sur la classe.


Crystal128-source-cpp.svg mainwindow.cpp
Implémentation de la classe de la fenêtre principale
#include <QtGui>
#include "mainwindow.h"

MainWindow::MainWindow()
{
}


Compiler le programme[modifier | modifier le wikicode]

La compilation s'effectue de la même façon que pour le programme précédent, excepté que la première commande (qmake -project) n'est plus nécessaire puisque l'on a déjà un fichier projet (essais.pro). Le nom de ce fichier projet détermine également le nom de l'exécutable (essais.exe sous Windows).

Exécution[modifier | modifier le wikicode]

Les bibliothèques de Qt sont nécessaires à l'exécution de tout programme Qt :

  • Par défaut, celles-ci sont compilées en mode liaison dynamique (.dll sous Windows, .so sous Unix/Linux). Cela signifie que les bibliothèques utilisées par l'application doivent de situer :
    • soit dans le même répertoire que l'exécutable,
    • soit dans un répertoire du PATH (sous Windows) ou de LD_LIBRARY_PATH (Unix/Linux).
  • Si les bibliothèques ont été compilées en mode liaison statique (configure -static), celle-ci sont directement intégrées à l'exécutable produit à la compilation.

Les bibliothèques en question sont en général :

  • QtCore4.dll et QtGui4.dll pour Qt (ou avec un d comme suffixe QtCore4d.dll et QtGui4d.dll en mode debug) ;
  • mingwm10.dll pour MinGW. Cependant celle-ci n'est pas toujours requise.

En exécutant le programme, on obtient une fenêtre vide.

Analyse[modifier | modifier le wikicode]

  • Le fichier essais.pro répertorie les différents fichiers du projet.
  • On déclare app objet de la classe QApplication et mainWin objet de la classe MainWindow.
  • MainWindow est une classe dérivée de QWidget à laquelle on ne va pour l'instant rien ajouter.

Explications[modifier | modifier le wikicode]

Crystal128-txt.svg essais.pro
Description du projet Qt
TEMPLATE = app
SOURCES  = main.cpp \
           mainwindow.cpp
HEADERS  = mainwindow.h

Dans ce fichier, on met tous les fichiers et les headers utilisés.

Crystal128-source-cpp.svg main.cpp
Fonction principale de lancement de l'application
#include <QApplication>
#include "mainwindow.h"

int main ( int argc, char *argv[] )
{
    QApplication app(argc, argv);
    MainWindow mainWin;
    mainWin.show();
    return app.exec();
}
#include <QApplication>

On inclue la création de fenêtres.

#include "mainwindow.h"

On inclue notre header. Attention de ne pas oublier les guillemets !

int main ( int argc, char *argv[] )
{
    //Code
}

On créé notre fonction principale.

    QApplication app(argc, argv);

On créé l'application.

    MainWindow mainWin;
    mainWin.show();

On appelle une fenêtre de type MainWindow et on l'affiche.

    return app.exec();

Exécution de l'application.

Notes et références[modifier | modifier le wikicode]


Signaux et slots

Dans le premier exemple du chapitre précédent, cliquer sur le bouton "Hello world!" ne déclenchait aucune action. Pour qu'un bouton puisse être utile, il faut connecter le signal clicked() à un slot ayant la même signature.

Définition[modifier | modifier le wikicode]

Les signaux et slots permettent d'interconnecter des objets Qt entre eux :

  • un signal est un évènement envoyé par un objet (exemple : clic de la souris sur un bouton) ;
  • un slot est une fonction réalisant l'action associée à un signal.

Tout objet Qt peut définir des signaux, et des slots pour recevoir des signaux en provenance d'autres objets Qt.

Conclusion : en appuyant par exemple sur un bouton, celui-ci envoie le signal clicked(). Quand on recevra ce signal de la part de ce bouton on va déclencher une action par un slot : par exemple la fenêtre qui quitte.

Définir un signal[modifier | modifier le wikicode]

Un signal est défini dans le fichier d'en-tête déclarant la classe :

Crystal128-source-h.svg Telechargement.h
(extrait) Définition du signal
class Telechargement: public QObject
{
    Q_OBJECT

    // ...

public signals:
    void fichierRecu(QString chemin_fichier);

    // ...
}


Aucune implémentation n'est à définir dans la classe. Le signal est utilisable dans la définition de la classe :

Crystal128-source-cpp.svg Telechargement.cpp
(extrait) Utilisation du signal
void Telechargement::Terminer()
{
    // Nettoyage...
    // ...
    // Signaler la fin
    emit fichierRecu( this->m_chemin_fichier );
}


Définir un slot[modifier | modifier le wikicode]

Un slot est similaire à une méthode de la classe :

  • Il doit être déclaré dans l'en-tête, dans une section slots ;
  • Il doit être implémenté dans la définition de la classe.
Crystal128-source-h.svg Stockage.h
(extrait) Déclaration des slots
class Stockage: public QObject
{
    Q_OBJECT

    // ...

public slots:
    bool stockerFichier(QString chemin_fichier);
    bool supprimerFichier(QString chemin_fichier);
    void finArchivage();

    // ...
}


Crystal128-source-cpp.svg Stockage.cpp
(extrait) Définition des slots
// ...

bool Stockage::stockerFichier(QString chemin_fichier)
{
    // ... copie du fichier spécifié dans le lieu de stockage
}

bool Stockage::supprimerFichier(QString chemin_fichier)
{
    // ... suppression du fichier spécifié
}

void finArchivage()
{
    // ... afficher le message "Fin de l'archivage"
}

// ...


Connexion[modifier | modifier le wikicode]

Un signal peut être connecté :

  • à plusieurs slots : la méthode slot de l'objet est appelée quand le signal est émis ;
  • à plusieurs autres signaux : l’émission du signal provoque également l'émission de ces autres signaux.

Un slot peut recevoir plusieurs signaux, c'est à dire qu'on peut connecter le même slot à plusieurs signaux.

La connexion entre un signal et un slot s'effectue en appelant la méthode statique connect de la classe QObject. Cette méthode possède 5 paramètres :

sender
L'objet source du signal ;
signal
Le signal émis par l'objet source;
receiver
L'objet receveur du signal ;
slot
Le slot du receveur connecté au signal ;
type
(optionnel) Type de connexion (automatique par défaut).

Seuls les 4 premiers sont obligatoires.

Exemple utilisant les classes Téléchargement et Stockage vues auparavant :

Crystal128-source-cpp.svg Main.cpp
(extrait) Connextion entre signaux et slots
// ...

Telechargement *telechargePage = new Telechargement( /*...*/ );
Stockage *stockageCleUsb = new Stockage( /*...*/ );

QtObject::connect(
    telechargePage, SIGNAL(fichierRecu(QString)),   // signal fichierRecu émis par telechargePage
    stockageCleUsb, SLOT(stockerFichier(QString))   // connecté au slot stockerFichier de stockageCleUsb
    );

// ...


Si on connecte plusieurs slots à un signal, il seront invoqués séquentiellement dans l'ordre où ils sont connectés. Par exemple, pour successivement copier puis supprimer le fichier et enfin afficher un message quand le téléchargement est terminé :

Crystal128-source-cpp.svg Main.cpp
(extrait) Connextion entre signaux et slots
// ...

QtObject::connect(
    telechargePage, SIGNAL(fichierRecu(QString)),
    stockageCleUsb, SLOT(stockerFichier(QString))
    );
QtObject::connect(
    telechargePage, SIGNAL(fichierRecu(QString)),
    stockageCleUsb, SLOT(supprimerFichier(QString))
    );
QtObject::connect(
    telechargePage, SIGNAL(fichierRecu(QString)),
    stockageCleUsb, SLOT(finArchivage())
    );

// ...


Le slot doit posséder une signature compatible avec le signal auquel il est connecté. C'est-à-dire :

  • Il doit posséder le même nombre de paramètre ou moins que le signal. Les paramètres manquants seront ignorés (voir l'exemple précédent pour le slot finArchivage() connecté au signal fichierRecu(QString)).
  • Ces paramètres doivent être du même type.
  • Un signal retourne toujours void.
  • Un slot peut retourner une valeur, cependant celle-ci est ignorée par le signal. Elle ne sert que si le slot est invoqué directement, comme n'importe quel autre méthode de la classe.

Utilisation[modifier | modifier le wikicode]

Maintenant, on peut donc découvrir l'exemple qui sera sûrement un des plus utilisés.

La classe QPushButton a un signal clicked(), qui s'active quand l'utilisateur clique sur le bouton. On le connecte donc au slot quit() de l'objet qApp, votre application.

Découverte de connect()[modifier | modifier le wikicode]

connect() est une méthode statique. On écrit donc :

QObject::connect();

La méthode connect prend 4 arguments :

  • Un pointeur vers l'objet qui émet le signal
  • Le nom du signal que l'on souhaite envoyer.
  • Un pointeur vers l'objet qui contient le slot récepteur.
  • Le nom du slot qui doit s'exécuter lorsque le signal se produit.

Exercice : la fenêtre se ferme après avoir cliquer sur un bouton[modifier | modifier le wikicode]

Lançons-nous dans la création du code de mafenetre.cpp.

//main.cpp
#include <QApplication>
#include "MaFenetre.h"
 
 
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
 
    MaFenetre fenetre;
    fenetre.show();
 
    return app.exec();
}
//MaFenetre.h
#ifndef DEF_MAFENETRE
#define DEF_MAFENETRE
 
#include <QApplication>
#include <QWidget>
#include <QPushButton>
 
class MaFenetre : public QWidget // On hérite de QWidget (IMPORTANT)
{
    public:
    MaFenetre();
 
    private:
    QPushButton *m_bouton; 
};
 
#endif
//MaFenetre.cpp
#include "MaFenetre.h"
 
MaFenetre::MaFenetre() : QWidget()
{
    setFixedSize(300, 150);
 
    m_bouton = new QPushButton("Quitter", this);
    m_bouton->setFont(QFont("Comic Sans MS", 14));
    m_bouton->move(110, 50);
 
    // Connexion du clic du bouton à la fermeture de l'application
    QObject::connect(m_bouton, SIGNAL(clicked()), qApp, SLOT(quit()));
}

Exécutons la commande qmake, puis testons notre code. Une fenêtre s'ouvre.

Rien de bien extraordinaire à première vue. Sauf que... si vous cliquez sur le bouton "Quitter", le programme s'arrête !

Utilisation de la méthode connect() pour afficher "A propos"[modifier | modifier le wikicode]

On peut faire un autre essai pour se faire un peu plus la main si vous voulez.

Je vous ai parlé d'un autre slot de QApplication : aboutQt(). Je vous propose de créer un second bouton qui se chargera d'afficher la fenêtre "A propos de Qt".

Voici le code:

//MaFenetre.h
#ifndef DEF_MAFENETRE
#define DEF_MAFENETRE
 
#include <QApplication>
#include <QWidget>
#include <QPushButton>
 
class MaFenetre : public QWidget // On hérite de QWidget (IMPORTANT)
{
    public:
    MaFenetre();
 
    private:
    QPushButton *m_quitter; 
    QPushButton *m_aPropos; 

};
 
#endif
#include "MaFenetre.h"
 
MaFenetre::MaFenetre() : QWidget()
{
    setFixedSize(300, 150);
 
    m_quitter = new QPushButton("Quitter", this);
    m_quitter->setFont(QFont("Comic Sans MS", 14));
    m_quitter->move(110, 50);
    QObject::connect(m_quitter, SIGNAL(clicked()), qApp, SLOT(quit()));
 
    m_aPropos = new QPushButton("A propos", this);
    m_aPropos->setFont(QFont("Comic Sans MS", 14));
    m_aPropos->move(110, 90);
    QObject::connect(m_aPropos, SIGNAL(clicked()), qApp, SLOT(aboutQt()));
}

On compile maintenant, et le bouton "Quitter" ferme toujours l'application. Quant à "À propos", il provoque l'ouverture de la fenêtre "À propos de Qt".

Dans ce code, nous sommes dans la classe MaFenetre, qui hérite de QWidget, et donc de QObject. Comme connect() appartient à QObject, dans ce cas, vous pouvez le supprimer avec les ::.

Paramétrage des signaux et des slots[modifier | modifier le wikicode]

La méthode statique connect() est assez originale, vous l'avez vu. Il s'agit justement d'une des particularités de Qt que l'on ne retrouve pas dans les autres bibliothèques.

Maintenant, comment faire un slider, à l'aide d'un QSlider qui quand la valeur change fait changer la valeur d'un afficheur LCD (QLCDNumber) ? Eh bien, tout simplement, il y a des paramètres : c'est-à-dire que le signal est valueChanged(int) et que le slot setDigitalCounter(int) reçoit le nombre envoyé par le slider. En fait, cela est simple, car on ne change vraiment pas beaucoup le code :

1 QSlider *m_slider = new QSlider();
2 QLCDNumber *m_lcd = new QLCDNumber();
3 connect(m_slider, SIGNAL(valueChanged(int)), m_lcd, SLOT(setDigitalCounter(int)));

On remarque donc qu'il suffit de seulement mettre le type de valeur et non la valeur elle-même, car elle varie en fonction du choix de l'utilisateur.

En travaux
link={{{link}}}

Cette page est en travaux. Tant que cet avis n'aura pas disparu, veuillez en considérer le plan et le contenu encore incomplets, temporaires et sujets à caution. Si vous souhaitez participer, il vous est recommandé de consulter sa page de discussion au préalable, où des informations peuvent être données sur l'avancement des travaux.


Projet Qt

Un projet Qt comporte un fichier d'extension .pro listant les fichiers du projet et permettant de configurer la compilation de l'application.

Syntaxe[modifier | modifier le wikicode]

Un fichier projet est un fichier texte dont la syntaxe ressemble à celle des Makefile.

Un commentaire commence par la caractère dièse # et se termine en fin de ligne. Il définit un certain nombre de variables en utilisant l'un des trois opérateurs =, += et -=. Ces variables contiennent en général une liste de valeurs qui peut être modifiée à l'aide de l'opérateur += pour ajouter un élément et de l'opérateur -= pour retirer un élément.

# Définir la valeur (remplace la valeur précédente)
VARIABLE = valeur1 valeur2

# Ajouter une ou des valeurs
VARIABLE += valeur3 valeur4

# Retirer une ou des valeurs
VARIABLE -= valeur2 valeur4

Créer un projet[modifier | modifier le wikicode]

Créer un fichier projet (*.pro) pour une application peut se faire de différentes façons :

  • Utiliser la commande suivante pour générer un fichier automatiquement à partir des fichiers sources du répertoire courant :
    qmake -project
  • Le créer manuellement avec un éditeur de texte,
  • Le créer avec Qt Creator.

Variables[modifier | modifier le wikicode]

Les variables sont de différent types :

  • celles qui listent les fichiers du projet,
  • celles qui permettent de configurer la compilation du projet.

Liste des fichiers[modifier | modifier le wikicode]

Les variables listant les fichiers du projet sont :

  • HEADERS : fichiers d'en-tête (*.h),
  • SOURCES : fichiers sources (*.cpp),
  • FORMS : fichiers formulaires d'interface utilisateur (*.ui),
  • RESOURCES : fichiers de ressources (*.qrc).
  • TRANSLATIONS : fichiers de traductions des messages de l'application (*.ts).

Configuration de la compilation[modifier | modifier le wikicode]

Les variables suivantes permettent de configurer la compilation du projet :

QT
Liste des modules Qt utilisés, sans le préfixe Qt. Pour pouvoir utiliser certaines classes, il faut ajouter les modules auxquels elles appartiennent. Par défaut QtCore et QtGui sont inclus. Par exemple, pour utiliser la classe QLocalSocket, il faut ajouter le module QtNetwork :
QT += network
Si une application n'utilise aucune interface utilisateur graphique, QtGui peut être enlevé :
QT -= gui
TEMPLATE
Modèle d'exécutable à générer. Cette variable n'est pas une liste de valeurs, et ne peut avoir que l'une des valeurs suivantes:
  • app : pour construire une application autonome
  • lib : pour construire une bibliothèque ou un plug-in.
  • vcapp : pour construire une application Visual C++ autonome
  • vclib : pour construire une bibliothèque ou un plug-in Visual C++.
  • subdirs : pour créer un makefile de compilation des sous-répertoires listés dans la variable SUBDIRS.
DEFINES
Liste des symboles définis lors de la compilation des fichiers sources.
TARGET
Nom du fichier exécutable produit. Par défaut, l'exécutable porte le même nom que le fichier projet (extension modifiée en .exe sous Windows).

Pour plus de détails, voir http://qt-project.org/doc/qt-4.8/qmake-variable-reference.html


Classes et objets Qt

Classe et objet[modifier | modifier le wikicode]

Quelques définitions de base :

  • Une classe définit les attributs et méthodes que possèdent les objets.
  • Un objet est une instance d'une classe. Il est en général possible de créer autant d'instances d'une classe que l'on veut.

Pour plus de détails, voir Programmation orientée objet et Programmation C++.

Classes et objets Qt[modifier | modifier le wikicode]

Un objet Qt n'est pas toujours un objet graphique car la bibliothèque ne se limite plus à l'interface graphique. Il peut s'agir d'un thread, d'une chaîne de caractères, ...

Toutes les classes d'objets Qt héritent de la classe QObject. Les classes de composants de l'interface héritent de la classe QWidget (elle-même héritant de la classe QObject).

Déclarer une classe Qt[modifier | modifier le wikicode]

Qt facilite l'utilisation des classes en C++, et permet d'obtenir des informations sur la classe d'un objet, sans utiliser RTTI. Une classe Qt étend une classe de la hiérarchie. Généralement il s'agit de QObject pour un objet non graphique.

class UneNouvelleClasse : public QObject
{
    Q_OBJECT

    // ...
}

La macro Q_OBJECT est nécessaire pour inclure les méta-informations sur les classes.


Extensions du langage C++

Qt étend la syntaxe du langage C++ avec de nouveaux mots-clés :

Compilation[modifier | modifier le wikicode]

Le code source Qt nécessite une phase supplémentaire avant la compilation en C++ afin de traduire la syntaxe étendue en syntaxe C++ compilable. Cette traduction est assurée par le MOC (Meta-Object Compiler).

Le résultat de cette traduction est stockée dans le sous-répertoire debug ou release sous la forme d'un fichier source dont le nom est le même que le fichier original, préfixé avec "moc_". En cas de problèmes, il est possible de vérifier (en dernier recours) les fichiers générés par MOC.

Pour plus de détails, voir http://qt-project.org/doc/qt-4.8/moc.html.

Boucle foreach[modifier | modifier le wikicode]


Qt Creator

Qt Creator est un IDE conçu avec Qt pour développer des projets avec Qt.

Il inclue divers outils et permet :

  • la gestion des projets (création de projets pré-remplis, configuration),
  • la compilation et l'exécution des applications,
  • la création de fenêtres et de widgets grâce aux outils Qt Designer et Qt Quick Designer intégrés,
  • la gestion de versions (Git, Subversion, Bazaar, Perforce, CVS et Mercurial).

Il permet également de créer plus facilement des applications pour portables, et de les compiler.

Fichiers d'en-tête[modifier | modifier le wikicode]

Bien qu'il soit fait pour Qt, les fichiers d'en-tête de sont pas inclus automatiquement, car il permet également de créer des applications n'utilisant pas Qt (C++ seul).

Par défaut, en utilisant Qt Designer, les fichiers d'en-tête sont inclus un à un : chaque classe de Qt possède son propre fichier d'en-tête portant le nom de la classe. Quand le code est créé manuellement, il est plus pratique d'utiliser le fichier d'en-tête QtGui incluant l'ensemble des autres fichiers d'en-tête permettant la création de fenêtres Qt:

#include <QtGui>

Lancement[modifier | modifier le wikicode]

Sous Windows, pour lancer Qt Creator :

  • si vous avez installé Qt SDK (sans compilation), le raccourci doit se trouver directement dans le sous-répertoire Qt SDK du menu démarrer.
  • si vous avez compilé Qt (pour Windows 64 bits notamment), lancez le programme qtcreator.exe situé dans le sous-répertoire bin du répertoire où vous avez compilé Qt Creator.

Description de l'interface[modifier | modifier le wikicode]

Qt Creator sous Windows 7

L'écran d'accueil au centre de la fenêtre propose des exemples de projets faisant la démonstration des fonctionnalités des bibliothèques de Qt. Ces mêmes exemples sont disponibles et exécutables en utilisant Qt Demo (qtdemo.exe) situé dans le sous répertoire bin des bibliothèques de Qt.

Les autres éléments de la fenêtres sont :

  • Le menu en haut de la fenêtre,
  • La barre latérale gauche des différentes perspectives de Qt Creator (raccourci Ctrl + numéro) :
    • Accueil est la perspective sélectionnée au démarrage.
    • Éditer présente la liste des fichiers des projets ouverts dans un arbre à gauche, et le fichier en cours d'édition à droite.
    • Design permet de créer et modifier des fenêtres et composants graphiques (fichiers *.ui) en utilisant Qt Designer.
    • Débogage permet le débogage des applications.
    • Projets permet de configurer la compilation des projets (chaîne de compilation à utiliser, étapes supplémentaires, ...).
    • Analyse est similaire à Éditer avec une partie analyse sous la partie éditeur de fichier, permettant de profiler l'application en cours d'exécution pour suivre les évènements (signaux) déclenchés.
    • Aide affiche l'aide sur Qt.
Sous la liste des perspectives, 4 boutons permettent de :
  • configurer rapidement les projets ouverts en mode release ou debug,
  • exécuter le projet courant,
  • déboguer le projet courant,
  • compiler le projet courant.
  • La barre inférieure contient :
    • Un outil de recherche multi-usage (recherche de fichiers, aller à une ligne ou une fonction particulière du code source, ...);
    • Différentes fenêtres de sortie (problèmes detectés, résultats de recherche, exécution, compilation) accessibles avec les touches Alt + numéro de 1 à 4.


Créer un projet avec Qt Creator

Qt Creator permet de créer et d'ouvrir plusieurs projets simultanément. Seul le projet actif est utilisé pour la compilation et l'exécution.

Ce chapitre montre comment créer un nouveau projet, ajouter des fichiers et le configurer.

Tutoriel

Cette page est également un tutoriel sur la création d'un projet qui sera utilisé dans les prochains chapitres du livre. Les étapes sont encadrées et utilisent ce style.

Créer un nouveau projet[modifier | modifier le wikicode]

Pour créer un nouveau projet :

  1. Sélectionnez "Nouveau fichier ou projet..." dans le menu "Fichier" (raccourci : Ctrl + N) ;
  2. Choisissez le type de projet à créer. Pour le tutoriel :
    1. choisissez "Autre projet" dans la section "Projets",
    2. choisissez "Projet Qt vide" ;
  3. Cliquez le bouton "Choisir..." ;
  4. Entrez le nom du projet (exemple : Test) et son emplacement puis cliquez le bouton "Suivant >" ;
  5. Choisissez le type de cible "Desktop" par exemple et cliquez le bouton "Suivant >" ;
  6. Si vous utilisez un gestionnaire de version, vous pouvez ajouter le projet ;
  7. Cliquez le bouton "Terminer".


Tutoriel : créez le projet Test
  1. Créez un projet nommé "Test" en suivant les étapes précédentes.

La perspective "Éditer" est sélectionnée et affiche l'arborescence des projets ouverts dont celui qui vient d'être créé. Cet arbre affiche les projets comme des nœuds racines dont les feuilles sont :

  • le fichier définissant le projet (*.pro),
  • les fichiers du projets classés dans des sous-répertoires virtuels en fonction de leur type :
    • les fichiers d'en-têtes (En-têtes *.h)
    • les fichiers sources (Sources *.cpp)
    • les fichiers définissant l'interface graphique avec Qt Designer (Formulaires *.ui)
    • ...
Présentation des fichiers d'un projet et le fichier projet correspondant.

Ajouter des fichiers à un projet[modifier | modifier le wikicode]

Une fois le projet créé (ou ouvert), des fichiers peuvent être créés (nouveau fichier) :

  1. Sélectionnez "Nouveau fichier ou projet..." dans le menu "Fichier" (raccourci : Ctrl + N) ;
  2. Choisissez le type de fichier dans la section "Fichiers et classes". Pour le tutoriel, choisissez "C++" > "Fichier source C++" ;
  3. Cliquez le bouton "Choisir..." ;
  4. Entrez le nom du fichier (exemple : main.cpp) puis cliquez le bouton "Suivant >" ;
  5. Si vous utilisez un gestionnaire de version, vous pouvez ajouter le fichier créé ;
  6. Cliquez le bouton "Terminer".

Pour ajouter des fichiers existants à un projet :

  1. Cliquez avec le bouton droit sur le projet et sélectionnez "Ajouter des fichiers existants" ;
  2. Sélectionnez les fichiers à ajouter au projet.

Ajouter une fenêtre principale au projet[modifier | modifier le wikicode]

Pour ajouter une fenêtre principale au projet :

  1. Sélectionnez "Nouveau fichier ou projet..." dans le menu "Fichier" (raccourci : Ctrl + N) ;
  2. Choisissez "Qt" > "Classe d'interface graphique Qt Designer" ;
  3. Choisissez "MainWindow" comme modèle ;
  4. Choisissez le nom de la classe ;
  5. Si vous utilisez un gestionnaire de version, vous pouvez ajouter le fichiers créés ;
  6. Cliquez le bouton "Terminer".


Tutoriel : ajoutez une fenêtre principale et créez le fichier main.cpp
  1. Ajoutez une fenêtre principale dont la classe est nommée MainWindow.
  2. Créez un fichier source nommé "main.cpp" en suivant les étapes de la section précédente, puis entrez le code suivant :
Crystal128-source-cpp.svg main.cpp
Fonction principale lançant l'application
#include <QtGui>
#include "mainwindow.h"

int main(int argc, char* argv[])
{
    QApplication app(argc, argv);
    MainWindow* win = new MainWindow();
    win->show();
    return app.exec();
}


Configuration des projets[modifier | modifier le wikicode]

  • Pour configurer la compilation des projets, utilisez la perspective "Projets".
  • Utilisez le menu contextuel du projet pour :
    • sélectionner le projet actif,
    • exécuter le projet (même s'il n'est pas actif),
    • fermer le projet.


Les widgets

Cette page présente certains widgets de Qt, ceux que vous utiliserez principalement.

Note : Pour ceux qui connaissent le HTML, la plupart de ces widgets sont transformés par le moteur web, qui en fait des objets Qt, puis par le compilateur en code machine (HTML → Moteur web → Qt → Compilateur → Binaire).

Introduction[modifier | modifier le wikicode]

Tout d'abord, bienvenue dans ce nouveau chapitre. Avant de voir tous ces widgets, apprenons les choses essentielles :

  • Pour créer un objet, nous avons deux possibilités :
1 QBlablabla *mon_blabla = new QBlablabla();
2 QBlabla mon_blablabla;
  • En suite, les objets possèdent des propriétés. Exemple : text. Pour y accéder, on utilisera la méthode text() et pour modifier, setText().
  • Les objets créés avec la première méthode utilisent des pointeurs -> et n'ont pas besoin de & pour accesseurs. À l'inverse, ceux de la deuxième méthode utilisent des pointeurs . et ont besoin de & pour accesseurs.

QWidget : le widget de base[modifier | modifier le wikicode]

QWidget est LE widget de base. QWidget hérite de QObject. Quand on envoie un widget, tel qu'il soit, s'il n'a pas de widget parent, la fenêtre sera lancée et prendra la taille de celui-ci. Voici des propriétés pour les QWidget.

Propriétés pour les widgets classiques comme pour les fenêtres[modifier | modifier le wikicode]

  • geometry : la méthode setGeometry() attend la taille du widget (L, l) et le positionnement du widget (x, y)
  • size : comme pour geometry, sauf que cette fois-ci, ce n'est que la taille qu'on attend
  • move : n'attend que le positionnement
  • height : la hauteur du widget
  • width : la largeur du widget

Propriétés utilisables uniquement avec les fenêtres[modifier | modifier le wikicode]

  • windowFlags : le type de fenêtre. Pour une fenêtre de type "Outil", il faut écrire : setWindowFlags(Qt::Tools);
  • windowIcon : l'icone de la fenêtre. setIcon() attend un objet QIcon qui attend lui-même le nom de l'image : setWindowIcon(QIcon("iconeLogiciel.png"));
  • windowTitle : le titre de la fenêtre. setWindowTitle("Mon programme en Qt");

Les widgets afficheurs[modifier | modifier le wikicode]

QLabel : afficher un texte ou une image[modifier | modifier le wikicode]

QLabel est un objet de Qt. Il permet d'afficher un texte ou une image.

Afficher du texte[modifier | modifier le wikicode]

QLabel avec pour valeur "Hello world !"
Un QLabel avec le texte "Hello world !"

Pour afficher du texte, il suffit d'écrire :

1 QLabel *m_texte = new QLabel(); // Création de l"objet
2 m_texte->setText("Hello world !"); // Définition du texte

La méthode à utiliser est donc setText(). Pour récupérer ce texte, utilisez la méthode text().

Afficher une image[modifier | modifier le wikicode]

Pour afficher une image, utilisez la méthode setPixmap() :

3 QLabel *m_image = new QLabel();
4 m_image->setPixmap(QPixmap("mon_image.png");

Vous pouvez utiliser la méthode pixmap() qui vous renvoie un QPixmap.

QProgressBar : une barre de progression[modifier | modifier le wikicode]

QProgressBar de valeur 50%
Une QProgressBar, avec pour valeur 50%

Pour afficher une barre de progression, il faut écrire :

1 QProgressBar *m_progressbar = new QProgressBar(); /* Création de la barre de progression */
2 m_progressbar->setValue(50); /* Choix de la valeur de la barre → 50 % */

On remarque la présence de la méthode setValue(), pour choisir la valeur de cet objet, et on en déduit qu'il faut utiliser value() pour récupérer cette valeur. Pour les signaux, il y a valueChanged() qui s'active quand la valeur change.

QLCDNumber : un label pour nombre[modifier | modifier le wikicode]

Un QLCDNumber est un label pour des nombres, mais dont l'écriture est type radio-réveil. On a la plupart des mêmes propriétés et signaux de QProgressBar pour le QLCDNumber.

QTableWidget : un tableau[modifier | modifier le wikicode]

Un QTableWidget est un widget pour afficher un tableau. Ce tableau a la particularité d'afficher automatiquement des barres de progression.

1 QTableWidget *m_tableau = new QTableWidget(); /* Création de l'objet */
2 m_tableau->setRowCount(5); /* Définition du nombre de lignes */
3 m_tableau->setColumnCount(1); /* Définition du nombre de colonnes */
4 
5 QTableWidgetItem *itemQt = new QTableWidgetItem(tr("Qt"), .arg(pow(row+1, column))); /* Création d'un objet QTableWidgetItem */
6 m_tableau->setItem(row, column, itemQt); /* Ajout de l'item */

On remarque que pour créer un item, on doit utiliser un objet spécialement créé pour cela, qui se nomme QTableWidgetItem. Le fonctionnement est un peu étrange, mais on aura souvent à changer seulement le texte. Dans ce cas, ce n'était pas très intelligent d'utiliser un QTableWidget car un QListView était plus adapté.

QListWidget : une liste[modifier | modifier le wikicode]

Un QListWidget est un widget pour liste. Il affiche automatiquement une barre de progression si besoin.

Les boutons[modifier | modifier le wikicode]

QPushButton : un bouton classique[modifier | modifier le wikicode]

Bouton de type classique
Un bouton classique, affichant le texte "Quitter"

QPushButton est une classe de Qt permettant de créer un bouton de type classique.

1 QPushButton *m_pushbutton = new QPushButton();
2 m_pushbutton->setText("Quitter");

Signaux[modifier | modifier le wikicode]

  • clicked() : est envoyé quand on clique sur le bouton
  • pressed() : est envoyé tant que le bouton est pressée
  • released() : est envoyé quand le bouton est relâché

Application :

3 connect(&m_pushbutton, SIGNAL(clicked()), qApp, SLOT(quit()));/* L'application quittera quand on cliquera sur le bouton */

Le QPushButton possède aussi la méthode setMenu(), qui permet de créer un bouton affichant un menu quand on clique dessus, en donnant une classe QMenu que nous étudierons dans un chapitre ultérieur.

QCheckBox : une case à cocher[modifier | modifier le wikicode]

Deux QCheckBox
Deux QCheckBox, mis en place grâce à un layout.

La case à cocher est présente dans Qt sous la forme d'un QCheckBox. Pour en créer une, il faut suivre le processus habituel :

1 QCheckBox *caseACocher = new QCheckBox(" J'aime Qt");

QRadioButton : un bouton radio[modifier | modifier le wikicode]

Les boutons radio sont des groupes de boutons dont un seul de ceux-ci peut être coché. Pour en créer, cela change car il faut créer un objet de type QGroupBox, pour définir quels boutons iront ensemble ("Je programme en Qt" et "J'habite à New York" ne feront pas parti du même objet QGroupBox). Observons donc le protocole :

Plusieurs QRadioButton réunis dans un QGroupBox
 1 QGroupBox *qgroupbox = new QGroupBox("Votre language de programmation préféré :"); /* Création du QGroupBox */
 2 QRadioButton *cPlusPlus = new QRadioButton("C++"); /* Création de l'option C++ ... */
 3 QRadioButton *python = new QRadioButton("Python"); /*..., de l'option Python ... */
 4 QRadioButton *php = new QRadioButton("PHP"); /*..., et de l'option PHP */
 5 
 6 QVBoxLayout *layout = new QVBoxLayout(); /* Création du layout */
 7 layout->addWidget(cPlusPlus);/* Ajout des QRadioButton */
 8 layout->addWidget(python);
 9 layout->addWidget(php);
10 
11 qgroupbox->setLayout(layout); /* Définition du layout pour l'objet QGroupBox */

Les champs[modifier | modifier le wikicode]

Les champs sont des widgets où l’utilisateur entre une information.

QLineEdit : un champ de texte à une ligne[modifier | modifier le wikicode]

Pour créer un champ de texte à une ligne en Qt, il faut créer un objet de type QLineEdit :

1 QLineEdit *m_lineEdit = new QlineEdit();
2 m_lineEdit->setPlaceholder("Ex: Qt");

QTextEdit : un champ de texte multi-ligne[modifier | modifier le wikicode]

Pour créer un champ de texte multi-ligne en Qt, c'est un objet QTextEdit qu'il faut créer :

1 QTextEdit *m_textedit = new QTextEdit();

QSpinBox : un champ de nombres[modifier | modifier le wikicode]

Image représentative d'un QSpinBox.
Un QSpinBox.

Un QSpinBox est un champ de texte pour nombres. Le protocole pour créer un objet de ce type est le suivant :

1 QSpinBox *m_spinbox = new QSpinBox();

Propriétés[modifier | modifier le wikicode]

  • step : le pas de déplacement des nombres.
  • minimum : la valeur minimale
  • maximum : la valeur maximale
  • prefix : un préfixe (texte avant le nombre)
  • suffix : un suffixe (texte après le nombre)


Modifions les propriétés ci-dessus :

2 m_spinbox->setStep(2); /* On se déplacera de 2 en 2 */
3 m_spinbox->setMinimum(0); /* La valeur minimale sera de 0 */
4 m_spinbox->setMaximum(100); /* La valeur maximale sera de 100 */

Exercice[modifier | modifier le wikicode]

Pour s'entraîner un peu, essayez de modifier la valeur d'un QProgressBar avec un QSpinBox.

QDoubleSpinBox : un champ de nombres non-entiers[modifier | modifier le wikicode]

Un QDoubleSpinBox est un QSpinBox à l'exception qu'il gère aussi les nombres non-entiers. Pour créer un objet de ce type, suivez le code suivant :

1 QDoubleSpinBox *m_doublespinbox = new QDoubleSpinBox(); /* Création de l'objet */

Propriétés[modifier | modifier le wikicode]

  • les mêmes que QSpinBox
  • decimal : le nombre de chiffres après la virgule

Modifions les propriétés :

2 m_doublespinbox->setMinimum(0);
3 m_doublespinbox->setDecimal(2); /* Il y aura deux chiffres après la virgule */

QSlider : un curseur[modifier | modifier le wikicode]

En Qt, QSlider est une classe permettant de créer un curseur. Voici comment créer un objet de ce type :

1 QSlider *m_slider = new QSlider();

Propriétés[modifier | modifier le wikicode]

  • orientation : l'orientation du QSlider
  • value : la valeur du QSlider

Signaux[modifier | modifier le wikicode]

  • valueChanged(int) : est envoyé quand la valeur change, autrement dit quand on déplace le curseur

Exercice[modifier | modifier le wikicode]

Comme plus haut dans cette page, vous pouvez contrôler un QProgressBar, mais avec cette fois-ci un QSlider.

QDial : un curseur en forme de cercle[modifier | modifier le wikicode]

Un QDial de valeur 135 environ.
Un QDial d'une valeur d'environ 135.

Le fonctionnement de QDial est quasiment le même que pour QSlider, cependant arrêtons-nous sur la méthode setValue(int) :

QDial *dial = new QDial();
dial->setValue(135);

Le nombre que représente le widget est un nombre en degrés (et non en radians).

QComboBox : une liste déroulante[modifier | modifier le wikicode]

Une liste déroulante, QComboBox, est l'équivalent de boutons radios (QRadioButton), à l'exception que celle-ci ne prend qu'une petite place même pour une grande liste.

1 QComboBox *m_combobox = new QComboBox(); /* Création de la liste */
2 m_combobox->addItem("Paris"); /* Ajout des options */
3 m_combobox->addItem("Tokyo");
4 m_combobox->addItem("Ottawa");

Propriétés[modifier | modifier le wikicode]

  • count : le nombre d'éléments dans la liste
  • currentId : l'id de l'élément sélectionné
  • currentText : le texte de l'élément sélectionné
  • editable : un booléen qui autorise ou non l'ajout de valeurs personnalisées. Si l'option est activée (elle ne l'est pas par défaut), les nouveaux éléments seront placés à la fin de la liste.

Maintenant, nous allons écrire un petit code :

5 QPushButton *boutonEnvoyer = new QPushButton("Envoyer !"); /* Création d'un bouton pour envoyer la valeur de la liste */
6 connect(boutonEnvoyer, SIGNAL(clicked()), this, SLOT(QMessageBox::information(this, "Capitale", ("Votre capitale est : " + m_combobox->currentText()))));

QComboBox a quelques classes filles, comme QFontComboBox, un liste déroulante pour les polices.

QDateEdit : un champ pour date[modifier | modifier le wikicode]

QDateEdit pour avec format anglophone
Un QDateEdit avec pour format yyyy-MM-dd.

Un QDateEdit se comporte à peu près comme un QSpinBox. Dans les propriétés, value est remplacé par date. On utilise aussi la propriété maximumDate et minimumDate. On remarque aussi dateFormat, pour le format de la date qui signifie YYYY-MM-DD, DD/MM/YYYY, etc...

Allez, un essai !

QDateEdit *qdateedit = new QDateEdit();
qdateedit->setMinimumDate(QDate(1715, 9, 1)); /* Mort de Louis XIV le 1er septembre 1715 */
qdateedit->setMaximumDate(QDate(3000, 12, 31)) /* Notre programme pourra servir jusqu'au 29ème siècle */
qdateedit->setDisplayFormat(QString("yyyy-MM-dd")); /* Format anglophone */
qdateedit->setDisplayFormat(QString("dd/MM/yyyy")); /* Format européen */

Vous remarquerez que les dates sont un peu étendues. Mais pour vous, ce sera au format anglophone ou européen ? La réponse est : au format européen, car displayFormat est prend le dernier format donné, et cela pareil pour toutes les propriétés.

QTimeEdit : un champ pour temps[modifier | modifier le wikicode]

QTimeEdit avec format européen
Un QTimeEdit avec pour format hh:mm:ss.

Un QTimeEdit se comporte comme QDateEdit. Sont remplacés les date par time.

1 QTimeEdit *qtimeedit = new QTimeEdit();
2 /* Horaires d'école */
3 qtimeedit->setMinimumTime(QTime(9, 30, 0)); /* Démarrage des cours à 09:30:00 */
4 qtimeedit->setMaximumTime(QTime(16, 0, 0)); /* Fin des cours à 16:00:00 */
5 qtimeedit->setDisplayFormat(QString("hh:mm:ss")); /* Heures:Minutes:Secondes */

QDateTimeEdit : un champ qui combine date et temps[modifier | modifier le wikicode]

QDateTimeEdit avec format de date anglophone et format d'heure européen
Un QDateTimeEdit avec pour format dd-MM-YYYY hh:mm:ss.

Comme indiqué dans le titre de cette section, l'objet QDateTimeEdit est une classe de Qt qui combine un QDateEdit et un QTimeEdit. Vous avez donc les propriétés de chacune des classes.

QCalendarWidget : un calendrier[modifier | modifier le wikicode]

QCalendarWidget de date minimale le 1er janvier 1970
Un QCalendarWidget avec pour valeur minimale le 1er janvier 1970.

Il se peut que vous n'aimiez pas la présentation de QDateEdit. Qt y a pensé ! Une classe QCalendarWidget est à notre disposition.

QCalendarWidget *m_calendar = new QCalendarWidget();
m_calendar->setMinimumDate(QDate(1970 /* Année*/, 1 /* Mois */, 1 /* Jour */));
m_calendar->setGridVisible(true); /* Affichons la grille */

Eh oui, c'est plutôt compliqué d'insérer une date minimale (setMinimumDate()) ou maximale (setMaximumDate()). Bien évidemment, c'est au format anglophone (YYYY-MM-DD) et non au notre (DD/MM/YYYY).

Les widgets conteneurs[modifier | modifier le wikicode]

Dans cette section, nous allons découvrir les widgets fait pour contenir. Car un QPushButton peut contenir un QProgressBar. Ah oui, ce n'est pas malin, mais cela nous prouve que Qt est flexible.

  • QFrame : une bordure
  • QGroupBox : pour contenir une catégorie de widgets (souvent utilisés pour les QRadioButton)
  • QTabWidget : un conteneur d'onglets

QFrame : une bordure[modifier | modifier le wikicode]

Le fonctionnement de QFrame est très simple :

1 QFrame *m_frame = new QFrame();
2 m_frame->setFrameStyle(QFrame::StyledPanel | QFrame::Raised) /* Exemple de bordure */

Ensuite, pour les widgets enfants, un setLayout(monLayout); qui contient lui-même des widgets.

QGroupBox : un conteneur pour une catégorie de widgets[modifier | modifier le wikicode]

 1 QGroupBox *conteneur = new QGroupBox();
 2 conteneur->setTitle("Mon conteneur");
 3 QProgressBar *progressBar = new QProgressBar();
 4 QPushButton *pushButton = new QPushButton("Coucou !");
 5 
 6 /* Layout */
 7 
 8 QVBoxLayout *layout = new QVBoxLayout();
 9 layout->addWidget(progressBar);
10 layout->addWidget(pushButton);
11 conteneur->setLayout(layout);

Vous pouvez aussi utiliser la propriété setAlignment() pour choisir l'alignement du titre (par défaut, celui-ci se trouve à gauche). À noter qu'il existe un constructeur tel que :

1 QGroupBox *conteneur = new QGroupBox();
2 conteneur->setTitle("Mon conteneur");
3 
4 /* = */
5 
6 QGroupBox *conteneur = new QGroupBox("Mon conteneur");

QTabWidget : un conteneur à onglets[modifier | modifier le wikicode]

Un QTabWidget est un conteneur à onglets. Il ne peut y avoir qu'un seul widget par onglets. Heureusement, un widget peut en contenir un autre, autrement dit vous pouvez mettre un layout qui contient tous les widgets que vous voulez.

 1 QTabWidget *onglets = new QTabWidget();
 2 
 3 QWidget *pageAccueil = new QWidget();
 4 
 5 QLabel *bienvenue = new QLabel("Bienvenue à tous");
 6 QPushButton *boutonQuitter = new QPushButton("Quitter");
 7 connect(boutonQuitter, SIGNAL(clicked()), qApp, SLOT(quit()));
 8 
 9 QVBoxLayout *layout = new QVBoxLayout();
10 layout->addWidget(bienvenue);
11 layout->addWidget(boutonQuitter);
12 
13 pageAccueil->setLayout(layout);
14 
15 QLabel *image = new QLabel();
16 image->setPixmap(QPixmap("monImage.png"));
17 
18 onglets->addTab(pageAccueil, "Accueil");
19 onglets->addTab(image, "Image");

Ce code affiche :

  • un onglet Accueil qui contient le texte de bienvenue et le bouton Quitter.
  • un onglet Image qui contient une image

Vous pouvez aussi mettre des QTabWidget dans des QTabWidget :

 1 QTabWidget *univers = new QTabWidget();
 2 QTabWidget *systemeSolaire = new QTabWidget();
 3 
 4 QWidget *pageSoleil = new QWidget();
 5 QWidget *pageMercure = new QWidget();
 6 QWidget *pageEtc = new QWidget();
 7 
 8 systemeSolaire->addTab(pageSoleil, "Soleil");
 9 systemeSolaire->addTab(pageMercure, "Mercure");
10 systemeSolaire->addTab(pageEtc, "...");
11 
12 univers->addTab(systemeSolaire, "Système solaire")

Exercices[modifier | modifier le wikicode]

Voici maintenant une liste d'exercices un peu plus complexe que ceux directement dans les sections appropriées, mais moins que par rapport à des TP :

  • Un champ de texte et un bouton dont ce dernier lance une boîte de dialogue avec le texte entré par l'utilisateur (renseignez-vous auprès de QMessageBox).
  • Deux boutons qui permettent d'augmenter et de diminuer la taille de la fenêtre
  • Des boutons radios et un label qui affiche l'option choisie (ex : un label "Acheter des frites/hamburgers/salades → options")
  • Un champ de texte qui modifie la valeur d'une des options (valeur personnalisée)

Entraînez-vous !

Bilan[modifier | modifier le wikicode]

Et bien, vous avez appris quelque chose d'essentiel. N'hésitez pas à relire et à pratiquer. Il est effectivement essentiel de pratiquer, car si vous allumez l'ordinateur à la fin de la lecture du livre, c'est très mauvais. Si quelque chose ne va pas, allez dans la page de discussion et posez la question. Notre prochaine étape est le positionnement des widgets. Si tout est bon, je vous invite au chapitre suivant →.


Le positionnement des widgets

Le positionnement des widgets est essentiel dans Qt. Nous travaillerons avec le positionnement absolu, et le plus utilisé, le positionnement relatif.

Le positionnement absolu[modifier | modifier le wikicode]

Le positionnement absolu est celui que nous avons vu jusqu'ici. Nous le reverrons en détail.

Utiliser le positionnement absolu[modifier | modifier le wikicode]

Nous avons plusieurs méthodes pour utiliser le positionnement absolu.

  • monWidget->move(50, 70); déplace le widget à l’abscisse (x) 50 et l'ordonnée (y) 70. Les attributs sont exprimées en pixels.
  • monWidget->setSize(24, 89); redimensionne le widget de 24 pixels de largeur et de 89 pixels de hauteur.
  • monWidget->setGeometry(50, 70, 24, 89); déplace le widget à l'abscisse 50 et à l'ordonnée 70 tout en lui donnant une largeur de 24 et une hauteur de 89.

Les défauts du positionnement absolu[modifier | modifier le wikicode]

Malheureusement, le positionnement absolu comporte des défauts. Essayez de redimensionner la fenêtre pour qu'elle soit la plus petite possible. Votre widget va se couper, ou bien, si vous faites une trèèès petite fenêtre, va disparaître ! C'est pour cela que nous allons découvrir un nouveau positionnement, le positionnement relatif.

Note : Si vous utilisez la méthode setFixedSize(), vous pouvez utiliser le positionnement absolu. C'est comme cela que fonctionne certains jeux.

Le positionnement relatif[modifier | modifier le wikicode]

Eh bien, l'heure est venue de découvrir le positionnement relatif. On utilisera 4 classes issus de QLayout : QHBoxLayout et QVBoxLayout, issues de la classe QBoxLayout (classe abstraite), QGridLayout et QFormLayout.

Principe des layouts[modifier | modifier le wikicode]

Le principe des layouts est simple : les widgets s'adaptent à la taillent de la fenêtre. Pour cela, ils utilisent des "grilles", numérotées :

Principe des layouts
0, 0 1, 0 ...
0, 1 1, 1 ...
... ... ...

Maintenant, attaquons-nous au code.

QHBoxLayout : layout horizontal[modifier | modifier le wikicode]

Dans ce premier layout, nous allons découvrir quelques méthodes, qui s'utiliseront aussi pour les autres layouts. Imaginons que vous voulez des boutons.

 1 QWidget *maPage = new QWidget(); /* Création de la page qui contiendra le layout */
 2 
 3 /* Création des boutons */
 4 QPushButton *bouton1 = new QPushButton("Wiki");
 5 QPushButton *bouton2 = new QPushButton("Books");
 6 
 7 QHBoxLayout *monLayout = new QHBoxLayout(); /* Création du layout */
 8 /* Ajout des widgets dans le layout */
 9 monLayout->addWidget(bouton1);
10 monLayout->addWidget(bouton2);
11 
12 maPage->setLayout(monLayout); /* Le layout appartient désormais à l'objet maPage */

On remarque les méthodes :

  • addWidget() : ajout d'un widget dans le layout.
  • setLayout() : définition du layout pour le widget demandé.

QVBoxLayout : layout vertical[modifier | modifier le wikicode]

Le fonctionnement de QVBoxLayout est le même que QHBoxLayout, à l’exception que cette fois-ci, c'est à la verticale. Autrement dit, je peux vous laisser remplacer les noms de classes.

QGridLayout : un layout en grille[modifier | modifier le wikicode]

Intéressants, les deux au-dessus, mais plus tard, vous aurez forcément besoin d'un layout en grille. C'est là qu'intervient QGridLayout : un layout en grille, comme le schéma du principe des layouts plus haut dans la page. Notre belle méthode addWidget() va se transformé :

 1 QPushButton *wi = new QPushButton("Wi"); /* Création des boutons */
 2 QPushButton *ki = new QPushButton("ki");
 3 QPushButton *books = new QPushButton("books");
 4 
 5 /* Introduction des boutons dans le layout */
 6 QGridLayout *m_layout = new QGridLayout();
 7 m_layout->addWidget(wi, 0, 0); /* En haut à gauche */
 8 m_layout->addWidget(ki, 1, 0); /* En haut à droite */
 9 m_layout->addWidget(books, 1, 1, 1, 2); /* En bas */
10 
11 /* Introduction du layout dans la page */
12 QWidget *m_page = new QWidget();
13 m_page->setLayout(m_layout);

Les deux premiers boutons sont tous les deux en haut, l'un à gauche et l'autre à droite. Mais le troisième bouton, lui est entièrement en bas car nous avons inséré deux nouveaux chiffres : rowSpan et columnSpan. On dit donc que le widget doit prendre 1 ligne en hauteur et 2 colonnes en hauteur. En réalité, il existe, comme on peut le voir dans la documentation, deux méthodes addWidget(). La première accepte le widget à insérer, puis les coordonnées. La deuxième, quant à elle, accepte le widget, la position x, la position y, la hauteur (rowSpan) et la largeur (columnSpan).

QFormLayout : un layout pour formulaire[modifier | modifier le wikicode]

Il se peut qu'un jour, vous voudriez mettre vos formulaires dans un layout. Mais c'est très long. C'est pour cela que QFormLayout à été créé : un layout spécialement fait pour les formulaires. Voici comment on s'en sert :

 1 /* Création des widgets */
 2 QLineEdit *nom = new QLineEdit();
 3 QLineEdit *langageProg = new QLineEdit();
 4 
 5 /* Création et introduction dans le layout */
 6 QFormLayout *monLayout = new QFormLayout();
 7 monLayout->addRow("Votre nom : ", nom);
 8 monLayout->addRow("Votre langage de programmation préféré : " langageProg);
 9 
10 /* Création et introduction dans la page **/
11 QWidget *maPage = new QWidget();
12 maPage->setLayout(monLayout);

Ce layout fonctionne de la manière suivante : avec la méthode addRow(), on met le libellé du champ et le nom du champ.

Combiner les layouts[modifier | modifier le wikicode]

C'est vite lassant un layout par programme. C'est pour cela qu'on peut les combiner !

 1 QLineEdit *nom = new QLineEdit();
 2 QLineEdit *prenom = new QLineEdit();
 3 
 4 QFormLayout *layoutFormulaire = new QFormLayout();
 5 layoutFormulaire->addRow("Votre nom : ", nom);
 6 layoutFormulaire->addRow("Votr prénom : ", prenom);
 7 
 8 QPushButton *boutonQuitter = new QPushButton("Quitter");
 9 
10 QVBoxLayout *layoutPrincipal = new QVBoxLayout();
11 layoutPrincipal->addLayout(layoutFormulaire); /* Utilisation de la méthode addLayout() */
12 layoutPrincipal->addWidget(boutonQuitter);
13 
14 QWidget *maPage = new QWidget();
15 maPage->setLayout(layoutPrincipal);

La méthode pour combiner les layouts est addLayout().


La fenêtre principale

La fenêtre principale permet l'utilisation de nombreux outils. Pour cela, on utilisera la classe QMainWindow.

Utiliser les outils de la fenêtre principale[modifier | modifier le wikicode]

Connaître les différents outils[modifier | modifier le wikicode]

Pour connaître les différents outils, quelque chose de simple :

  • Les menus : Fichier, Édition, ...
  • La barre d'outils : les petites icônes, dans Qt Creator Compiler, Exécuter, Déboguer, etc...
  • Les docks : rarement utilisés, ce sont par exemple la liste des fichiers ouverts dans Qt Creator.
  • La zone centrale : la partie la plus importante, dans Qt Creator le code source.
  • La barre d'état : comme son nom l'indique, l'état de la fenêtre. Par exemple, dans un navigateur web, vous pourrez avoir la durée de chargement.

Les menus[modifier | modifier le wikicode]

Pour notre chapitre, nous irons de haut en bas, et c'est bien pour cela que nous commençons avec les menus. C'est le plus utilisé (si on ne compte pas la zone centrale), et la grande majorité des programmes en ont. Pour commencer, nous allons étudier un code :

1 QMenu *menuFichier = menuBar()->addMenu("Fichier", this);

Première ligne de code, premier changement ! Eh bien oui, c'est la méthode addMenu() de menuBar() que nous allons appeler. À noter : nous sommes dans une classe qui dérive de QMainWindow, si vous regardez bien. Si votre code n'est que dans un seul fichier (trèèès mauvais), vous devrez écrire maFenetrePrincipale->menuBar()->addMenu().

Ajouter une action[modifier | modifier le wikicode]

C'est bien beau, mais, si vous compilez, et que vous cliquez sur votre menu, rien ne s'ouvre ! Qt ne sait absolument pas que le menu Fichier contiendra une action Nouveau, et c'est ce que nous allons faire :

2 QAction *actionNouveauFichier = new QAction("Nouveau fichier");
3 menuFichier->addAction(actionNouveauFichier);

Il faudra penser à rajouter des actions. Autre chose, il y a juste marqué Nouveau fichier. C'est banal ! Arrangeons ça !

4 actionNouveauFichier->setIcon(QIcon("nouveau-fichier.png"));
5 actionNouveauFichier->setShortcut(QKeySequence("Ctrl+N"));

Et si notre action est Gras, on peut faire ceci :

1 QAction *actionGras = new QAction("Gras");
2 actionGras->setIcon(QIcon("gras.png"));
3 actionGras->setCheckable(true);
4 menuEdition->addAction(actionGras);
Attention !
link={{{link}}}

Dans le système d'exploitation Mac OS X, vous ne pouvez pas créer d'action du nom de “Quitter“, car celle-ci est créée automatiquement par l'OS.

Créer des sous-menus[modifier | modifier le wikicode]

Si la personne a par exemple la liste des fichiers récents, il faut procéder comme ceci :

1 QMenu *menuFichier = menuBar()->addMenu("Fichier", this);
2 QMenu *menuFichiersRecents = new QMenu("Fichiers récents");
3 QAction *actionFichierPro = new QAction("Un certain fichier *.pro");
4 QAction *actionFichierH = new QAction("Un certain fichier *.h");
5 QAction *actionFichierCpp = new QAction("Un certain fichier *.cpp");
6 menuFichiersRecents->addAction(actionFichierPro);
7 menuFichiersRecents->addAction(actionFichierH);
8 menuFichiersRecents->addAction(actionFichierCpp);
9 menuFichier->addMenu(menuFichiersRecents);

Cette fois-ci, on utilise la méthode addMenu().

La barre d'outils[modifier | modifier le wikicode]

Pour afficher des actions dont l'utilisateur aura le plus besoin, on utilise la barre d'outils qui nous permet de ne pas passer par les menus. Et ce qui est très pratique, c'est que nous pouvons réutiliser toutes les actions du menu !

1 QToolBar *barreDoutilsFichier = addToolBar("Fichier");
2 QAction *actionQuitter = new QAction("Fermer la fenêtre");
3 barreDoutilsFichier->addAction(actionQuitter);

Les docks[modifier | modifier le wikicode]

Exemple de QDockWidget.
Un QDockWidget qui contient un QCalendarWidget.

Le principe des docks est assez simple : la classe QDockWidget contient nos widgets, et on les ajoute à la QMainWindow :

1 QDockWidget *dock = new QDockWidget(tr("Dock Widget"), this);
2 QPushButton *button = new QPushButton(tr("Button in a Dock Widget"));
3 dock->setWidget(button);
4 addDockWidget(Qt::LeftDockWidgetArea, dock);

On vient donc d'insérer un dock qui sera placé à gauche de la fenêtre. Pour ajouter plusieurs widgets dans un même dock, on peut utiliser un layout puis la méthode setLayout() de la classe QDockWidget. Bien évidemment, l'utilisateur pour en faire une fenêtre à par entière qu'il pourra ensuite remettre autant à gauche qu'à droite.

L'espace principal[modifier | modifier le wikicode]

Pour l'espace principal, il y a deux choix : un SDI, c'est-à-dire une seule fenêtre dans la fenêtre, ou un MDI, c'est-à-dire plusieurs fenêtres qui vont se glisser dans le cadre principal.

SDI[modifier | modifier le wikicode]

Pour créer un SDI (Single Document Interface), c'est très simple. Vous créez un widget conteneur (souvent un QWidget), puis vous utilisez la méthode setCentralWidget(), qui accepte votre conteneur.

MDI[modifier | modifier le wikicode]

Pour l'espace MDI (Multiple Document Interface), c'est un peu différent. Voici un exemple :

1 QMdiArea *zoneMDI = new QMdiArea();
2 
3 QPushButton *button = new QPushButton();
4 QDateEdit *dateEdit = new QDateEdit();
5 
6 QMdiSubWindow *mdiSubWindow1 = zoneMDI->addSubWindow(button);
7 QMdiSubWindow *mdiSubWindow2 = zoneMDI->addSubWindow(dateEdit);
8 
9 setCentralWidget(zoneMDI);

Effectivement, nous utilisons le principe du SDI car on remarque setCentralWidget(). Pour notre MDI, la fenêtre n'a pas ses “propres” outils pour en créer, mais on utilise la classe QMdiArea qui contiendra des QMdiSubWindow, qu'on ajoute avec la méthode addSubWindow() d'une QMdiArea. Ces QMdiSubWindow contiendront les widgets de la sous-fenêtre.

À Retenir...
link={{{link}}}
  • Pour créer un SDI, on utilise un widget simple qu'on ajoute avec setCentralWidget().
  • Pour créer un MDI, on utilisera un widget QMdiArea, qui contiendra des QMdiSubWindow, qui seront ajoutés avec la méthode addSubWindow().


La barre d'état[modifier | modifier le wikicode]

Aussi appelée barre de statut, la barre d'état est un “bandeau” en bas de la fenêtre qui indique l'état de la fenêtre. Regardez l'exemple ci-dessous :

1 statusBar()->showMessage(tr("Bienvenue !"), 2000);
2 QProgressBar *progressBar = new QProgressBar();
3 progressBar->setValue(75);
4 statusBar()->addWidget(progressBar, 16);

Ici, nous supposons que nous sommes dans une classe de type QMainWindow, qui intègre directement la classe qui permet de créer une barre d'état : QStatusBar. Nous utilisons le plus souvent ces méthodes : showMessage() et addWidget(). La première méthode permet d'afficher un message, avec deux choix : soit nous indiquons directement le message, qui s'affichera alors jusqu'à ce que l'utilisateur passe dessus avec la souris ou qu'un autre message s'affiche, soit nous indiquons et le message et le temps qu'il doit rester, en millisecondes (vous prenez le nombre de secondes et vous multipliez par 1000). La deuxième méthode permet d'insérer un widget dans la barre d'état, ici une barre de progression, mais cela peut être un bouton, un champ, etc...


TP : un éditeur de texte

Dans ce TP, vous apprendrez à créer un éditeur de texte.

Découvrir le sujet[modifier | modifier le wikicode]

Avant d'attaquer ce TP, il est important de connaître le sujet.

Ouvrir un fichier[modifier | modifier le wikicode]

Nous allons donc commencer par l'ouverture du fichier. On utilise la classe QFile.


Traduire son programme

Il peut arriver que vous distribuez votre programme à un ami. Imaginons qu'il soit anglais. Même s'il parle français, il préférerait avoir le programme en anglais. C''est pour cela qu'on peut traduire le programme. Tout d'abord, configurons le monprojet.pro.

Configurer le projet[modifier | modifier le wikicode]

 1 #-------------------------------------------------
 2 #
 3 # Project created by QtCreator 2018-10-10T14:20:39
 4 #
 5 #-------------------------------------------------
 6 
 7 QT       += core gui
 8 
 9 greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
10 
11 TARGET = monprojet
12 TEMPLATE = app
13 
14 
15 SOURCES += main.cpp\
16         mainwindow.cpp
17 
18 HEADERS  += mainwindow.h
19 
20 FORMS    += mainwindow.ui

Pour l'instant, vous avez ceci. Maintenant, rajoutez la ligne :

1 TRANSLATIONS += monprojet_fr.ts monprojet_en.ts

Voilà, votre fichier .pro est configuré. Rendez-vous maintenant dans vos fichiers .cpp. Ajoutez autour de vos chaînes de caractères tr(). Cette fois-ci, c'est dans la console (Ctrl + Alt + T sous GNU/Linux) que nous avons rendez-vous. Entrez la ligne suivante :

lupdate monprojet.pro

Vous pouvez maintenant voir des fichiers .ts générés.

Les fichiers .ts et .qm[modifier | modifier le wikicode]

Quand vous avez installé Qt, un programme nommé Qt Linguist a aussi été installé. Allez-y.

Ouvrez les fichiers en question, puis rentrez dans les champs English Translation, par exemple, le texte traduit. Fermez ensuite le programme, et ouvrez la console :

lrelease monprojet_fr.ts monprojet_en.ts

Cela créé des fichiers .qm. Mettez-les maintenant dans le dossier de l'exécutable. Ouvrez le fichier main.cpp et entrez :

1 QTranslator translator;
2 translator.load("monprojet_en");
3 app.installTranslator(&translator);

Lancez maintenant le programme. Le programme est traduit en anglais ! Bien évidemment, cela marche pour le chinois, l'arabe, l'italien...


Sauvegarder des données avec XML

Pour communiquer avec les fichiers XML, il faut d'abord importer le nouveau module du nom de QtXml. Ajoutez la ligne #include <QtXml> à chaque début de fichier qui communique avec l'XML. Dans le fichier .pro, ajoutez la ligne QT += xml. Sous Windows, il faudra mettre les fichiers DLL QtXmld4.dll et QtXml4.dll.

Utilisation du module QtXml[modifier | modifier le wikicode]

Création du fichier[modifier | modifier le wikicode]

Bien évidemment, il faut créer le fichier. Par exemple, un fichier wikimediaprojects.xml :

1 <?xml version="1.0" encodage="UTF-8" ?>
2 <wikimedia>
3     <project>Wikipedia</project>
4     <project>Wikibooks</project>
5     <project>Wikimedia Commons</project>
6 </wikimedia>

Ce n'est qu'un exemple.

Chargement du fichier[modifier | modifier le wikicode]

Pour charger le fichier, on utilise deux classes : QDomDocument et QFile. Voici maintenant la méthode :

 1 QDomDocument *dom = new QDomDocument("xml");
 2 QFile xml_doc("wikimediaprojects.xml");
 3 if(!xml_doc.open(QIODevice::ReadOnly)) /* On teste l'ouverture du fichier */
 4 {
 5 	QMessageBox::warning(this,"Erreur à l'ouverture du document XML","Le document XML n'a pas pu être ouvert.");
 6 }
 7 if (!dom->setContent(&xml_doc)) /* On teste l'attribution du fichier, c'est-à-dire qu'on met le document XML dans l'objet QDomDocument */
 8 {
 9 	xml_doc.close();
10 	QMessageBox::warning(this, "Erreur à l'ouverture du document XML", "Le document XML n'a pas pu être attribué à l'objet QDomDocument.");
11 }
12 
13 xml_doc.close(); /* Maintenant, on peut fermer le fichier car tout est dans le QDomDocument */

Lecture du fichier[modifier | modifier le wikicode]

Maintenant, il faut récupérer ce qu'il y a dedans. Nous allons voir plusieurs méthodes pour récupérer des informations.

text()[modifier | modifier le wikicode]

La première méthode est la méthode text(). On l'utilise comme ceci :

 1 /* Code précédent à introduire */
 2 
 3 QDomElement elementWikimedia = dom.documentElement();
 4 QDomNode noeudProject = elementWikimedia.firstChild();
 5 
 6 QListWidget *listeProjects = new QListWidget();
 7 
 8 while(!noeudProject.isNull())
 9 {
10     elementProject = noeudProject.toElement; /* Transformation du noeud en élément */
11     if(!elementProject.isNull())
12     {
13     	QListWidgetItem *itemProject = new QListWidgetItem(elementProject.text()); /* On met le texte de l'élément dans l'item de la liste */
14     	listeProjects->addItem(itemProject); /* Et on place l'item dans la liste */
15     	noeudProject = noeudProject.nextSibling();
16     }
17 }

attribute()[modifier | modifier le wikicode]

Imaginons maintenant que vous avez un fichier comme ceci :

<?xml version="1.0" encoding="UTF-8" ?>
<wikimedia>
    <project lang="en">Wikibooks</project>
    <project lang="fr">Wikilivres</project>
</wikimedia>

Si on souhaite préciser la langue, on pourra par exemple mettre ceci :

1 QListWidgetItem *itemProject = new QListWidgetItem(QString(elementProject.text() + " (" + elementProject.attribute("lang", "?") + ")")); /* Cette fois-ci, on précise la langue entre parenthèses en combinant les QString */
2 listeProjects->addItem(itemProject);

Écriture dans le fichier[modifier | modifier le wikicode]

Pour écrire dans le fichier, il faudra créer les éléments puis les introduire dans le fichier, que ce soit tous d'un coup ou un par un (la meilleure méthode est la première). Le principe est simple : on récupère l'ensemble du fichier, on le modifie, et enfin on remplace tout le fichier par le nouveau contenu.

Bilan[modifier | modifier le wikicode]

Maintenant que vous avez appris à vous servir de l'XML, cela sera très intéressant. Il permettra d'enregistrer diverses informations, par exemple des scores pour un jeu vidéo, ou encore des marques-pages pour un navigateur web. Tiens, mais quel est le prochain chapitre ? C'est la réalisation d'un navigateur web !


Sauvegarder des données avec SQL

Dans ce nouveau chapitre sur la programmation Qt, nous allons voir comment sauvegarder des données avec SQL. Pour que cela marche, il faut absolument insérer au début de votre code la ligne #include <QSql>, car nous allons utiliser le module ... QSql.

Se connecter à la base de données[modifier | modifier le wikicode]

Avant toute chose, vérifiez que vous avez un SQL.

Pour plus de détails voir : Programmation SQL.

Ensuite, en fonction de votre langage SQL, vous aurez différents drivers. Pour MySQL, ce sera QMYSQL, pour PostgreSQL, ce sera QPSQL. Pour voir la liste complète, voir la documentation. Exemple avec MySQL.

 1 QSqlDatabase sqlDb = QSqlDatabase::addDatabase("QMYSQL", "test-wikilivres");
 2 sqlDb.setHostName("localhost");
 3 sqlDb.setUser("wikilivres");
 4 sqlDb.setPassword("mot-de-passe-secret");
 5 sqlDb.setDatabase("wikilivres");
 6 if (sql.open)
 7 {
 8     statusBar()->showMessage(tr("La base de données a bien été chargée !"), 5000)
 9 }
10 
11 else
12 {
13     QMessageBox::critical(this, tr("Échec de connexion"), QString(tr("Impossible de se connecter à la base de données : ") + sqlDb.lastError().text() + tr(".")));
14 }

Exécuter une requête[modifier | modifier le wikicode]

Pour exécuter une requête SQL, nous allons utiliser la classe QSqlQuery. Elle s'utilise de cette manière, et affecte la dernière base de données ouverte (avec la méthode open) :

1 QSqlQuery query;
2 query.exec("SELECT * FROM wikilivres ORDER BY page");

Pour récupérer les données, vous faites ensuite :

1 while (query.next()) {
2     QString pageName = query.value(0).toString();
3     int page = query.value(1).toInt();
4 }

Si les valeurs avec lesquelles vous voulez trier les données changent dans votre programme, vous pouvez utiliser les méthodes prepare(), addBindValue() et bindValue().

1 query.prepare("SELECT * FROM wikilivres WHERE id < :max & id > :min");
2 query.bindValue(":max", 100);
3 query.bindValue(":min", 0);
4 query.exec();

Ou encore :

1 query.prepare("SELECT * FROM wikilivres WHERE id < ? & id > ?");
2 query.addBindValue(100);
3 query.addBindValue(0);
4 query.exec();

Quand il y a une ou deux valeurs, on peut utiliser les points d'interrogation, mais quand c'est plus, on peut attribuer des noms aux valeurs de la requête.


Qt Designer

Introduction[modifier | modifier le wikicode]

Attention !
link={{{link}}}

Il vaut mieux savoir coder avec Qt avant d'utiliser Qt Designer.

Qt designer est une série d'outils intégrés dans Qt Creator permettant de créer graphiquement des interfaces graphiques de l'application. Lors de la compilation elles seront automatiquement reconverties en c++ et donc utilisables comme des classes normales.

Utilisation[modifier | modifier le wikicode]

Qt Designer 4.3.4

Incorporation[modifier | modifier le wikicode]

Après avoir dessiné l'interface, enregistrez votre fichier (pour l'exemple ce sera widget.ui). Dans le fichier essais.pro, ajoutez la ligne :

 FORMS = widget.ui


Pour l'exploiter dans un programme il faudra créer une classe héritant du widget de cette manière :

Crystal128-source-h.svg mainwindow.h
Classe basique de fenêtre graphique
#include <QWidget>
#include "ui_widget.h"

class MainWindow : public QWidget, public Ui::Widget
{
public:
    MainWindow(QWidget *parent = 0);
};


Crystal128-source-cpp.svg mainwindow.cpp
Classe basique de fenêtre graphique
#include <QtGui>

MainWindow::MainWindow(QWidget *parent) : QWidget(parent)
{
    setupUi(this);
}



Présentation[modifier | modifier le wikicode]

Qt Designer est disponible en lançant Qt Creator depuis Menu démarrer > Tous les programmes > Qt SDK > Qt Creator (windows).

Copie d'écran de des outils Qt designer intégrés à Qt Creator sous Windows 7.

Code[modifier | modifier le wikicode]

L'exemple est une calculatrice à fabriquer sous Qt designer.

Le tableau ci-dessous liste les composants de la fenêtre :

Tableau
Widget Nom de l'objet

QSpinBox

nombre1

QComboBox

operation

QSpinBox

nombre2

QPushButton

boutonEgal

QLabel

resultat

.pro[modifier | modifier le wikicode]

Il faut modifier le fichier .pro :

######################################################################
# Automatically generated by qmake (2.01a) lun. 2. juin 12:00:20 2008
######################################################################

TEMPLATE = app
TARGET = 
DEPENDPATH += .
INCLUDEPATH += .

# Input
FORMS += calculatrice.ui
SOURCES += main.cpp

ATTENTION ! Il faut faire qmake, make pour lancer, et ne pas mettre qmake -project, sinon Qt régénérera un un fichier .pro normal.

main.cpp[modifier | modifier le wikicode]

voici le main.cpp:

#include <QApplication>
#include <QtGui>
#include "ui_calculatrice.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QWidget *fenetre = new QWidget;
    Ui::FenCalculatrice ui;
    ui.setupUi(fenetre);

    fenetre->show();

    return app.exec();
}

FenCalculatrice.cpp[modifier | modifier le wikicode]

#include "FenCalculatrice.h"

FenCalculatrice::FenCalculatrice(QWidget *parent) : QWidget(parent)
{
    ui.setupUi(this);

    connect(ui.boutonEgal, SIGNAL(clicked()), this, SLOT(calculerOperation()));
}

header files (.h)[modifier | modifier le wikicode]

FenCalculatrice.h

#ifndef HEADER_FENCALCULATRICE
#define HEADER_FENCALCULATRICE

#include <QtGui>
#include "ui_calculatrice.h"

class FenCalculatrice : public QWidget
{
    Q_OBJECT

    public:
        FenCalculatrice(QWidget *parent = 0);

    private slots:
        /* Insérez les prototypes de vos slots personnalisés ici */

    private:
        Ui::FenCalculatrice ui;
};


#endif

Liens externes[modifier | modifier le wikicode]


Utiliser la documentation Qt

Voici un chapitre important sur l'apprentissage de Qt : celui qui vous aidera à comprendre la documentation de Qt. Celui-ci explique toutes les possibilités de la bibliothèque. La documentation de Qt contient la liste des fonctionnalités de Qt. Toutefois la documentation Qt est en anglais comme quasiment toutes les documentations en programmation.

Les bases[modifier | modifier le wikicode]

Une documentation est mise à disposition par le site de Qt. Elle est complète et permet de trouver tout pour faire son programme. Il y a 2 moyens d'accéder à la documentation :

  • Internet : sur le site du projet Qt
  • Hors-Ligne : le programme Qt Assistant permet d'accéder à la documentation.

Avec Internet[modifier | modifier le wikicode]

Vous pouvez consulter la documentation en ligne du projet Qt disponible sur http://doc.qt.io

En allant sur la documentation en ligne, cela vous permet d'accéder à la documentation la plus à jour sur les nouveautés ou les bugs corrigés et limitations.

Hors-ligne[modifier | modifier le wikicode]

Si vous n'avez pas accès à l'Internet, vous pouvez quand même consulter la documentation qui a été installée sur votre ordinateur avec Qt. Pour cela, sous Windows, il vous suffit d'aller dans Démarrer puis dans le répertoire où se trouve Qt et de lancer l'application Qt Assistant. Celle-ci comporte plusieurs fonctionnalités comme ouvrir plusieurs onglets, mettre en favoris des pages et plusieurs autres.

Sous GNU/Linux, allez dans le menu programmation et choisissez Qt Assistant.

Les différentes sections[modifier | modifier le wikicode]

Sur cette page (ou celle correspondant à la version de Qt que vous utilisez), il y a différentes sections dont certaines sont détaillées ci-dessous.

Getting Started[modifier | modifier le wikicode]

Getting Started contient des informations importantes pour débuter. On trouve dans cette section :

  • What's new in Qt x.y : qu'est-ce qu'il y a de nouveau dans cette version de Qt par rapport aux précédentes ? Cette page servira plutôt aux programmeurs utilisant une version précédente et voulant savoir ce qu'il y a de nouveau dans celle-ci. Vous pouvez tout de même y jeter un coup d’œil.
  • How to Learn Qt : comment apprendre Qt ? Cette page vous donne certains conseils pour apprendre Qt dans les meilleures conditions. toutefois, toute la documentation est en anglais donc cette section aussi.
  • Installation : comment installer Qt.
  • Tutorial and Examples : le tutoriel de Qt et des programmes d'exemple avec leur code source.
  • Porting from Qt 3 and Qt 4 : quels sont les changements majeurs entre Qt 3 et Qt 4 ?


Ressources

Consultez également ces pages dans d’autres projets Wikimedia :

Ressources multimédia sur Commons.
Article encyclopédique sur Wikipédia.

Livres connexes[modifier | modifier le wikicode]

  • Programmation C++ pour apprendre le langage de programmation utilisé par défaut par Qt.
  • PyQt utiliser Qt avec le langage Python.
  • Programmation C pour apprendre le langage dont est dérivé le C++, qui permet lui aussi la création de GUI.

Liens externes[modifier | modifier le wikicode]

GFDL GFDL Vous avez la permission de copier, distribuer et/ou modifier ce document selon les termes de la licence de documentation libre GNU, version 1.2 ou plus récente publiée par la Free Software Foundation ; sans sections inaltérables, sans texte de première page de couverture et sans texte de dernière page de couverture.