Você está na página 1de 187

La FAQ Qt

Date de publication : 12/09/2006

Dernière mise à jour : 02/01/2010

La troisième version de Qt a été largement améliorée avec la sortie de la dernière


version majeure : Qt 4. Qt est maintenant disponible sur les trois plateformes
traditionnelles sous triple licences. Ce framework a été retravaillé en profondeur, bien
des objets ont été transformés, supprimés ou ajoutés, afin de permettre à l'utilisateur
de la bibliothèque de profiter pleinement de la puissance offerte par Qt.

Ici, l'équipe rédactionnelle souhaiterait remercier tous ceux qui ont contribué à
cette FAQ : Alp, Aurélien Régat-Barrel, dourouc05, Gulish, haraendil, Ikipou,
IrmatDen, johnlamericain, Kinji1, LeGars, LittleWhite, Mac&Cheese, Matthieu
Brucher, nouknouk, Nykoo, Niak74, Shugo78, superjaja, yan, zAmnellL.
Ont contribué à cette FAQ :

Jonathan Courtois - Niak74 - LittleWhite - nouknouk - LeGars -


Thibaut Cuvelier (Site web) ( Blog ) - Matthieu Brucher (http://
miles.developpez.com/) ( Blog ) - Alp Mestan (Site perso de
Alp) ( Blog ) - Yan Verdavaine (Site web) - Denys Bulant
(Tutoriels Qt) - Shugo78 - Nykoo - mac&cheese - Benjamin
Poulain - François Jaffré - Kinj1 (Site web) - gulish - haraelendil
- Louis du Verdier - Aurelien.Regat-Barrel (Site web) -
La FAQ Qt

1. Introduction à Qt4 (5) ............................................................................................................................................................... 4


2. Généralités (10) ......................................................................................................................................................................... 7
2.1. Mémoire (3) .................................................................................................................................................................... 10
2.2. Déploiement (1) .............................................................................................................................................................. 13
2.3. Contribuer (2) ................................................................................................................................................................. 14
3. Le contenu de Qt4 (2) ............................................................................................................................................................. 16
4. La compilation (10) ................................................................................................................................................................. 18
4.1. Généralités sur la compilation (8) ..................................................................................................................................19
4.2. qmake (2) ........................................................................................................................................................................ 25
5. QtCore (80) ..............................................................................................................................................................................26
5.1. QObject (5) ..................................................................................................................................................................... 38
5.2. QString (10) .................................................................................................................................................................... 42
5.3. Thread (9) ....................................................................................................................................................................... 48
5.4. Fichiers et répertoires (22) ............................................................................................................................................. 55
5.4.1. Opérations de base (10) .........................................................................................................................................56
5.4.2. Lecture et écriture (3) ............................................................................................................................................64
5.4.3. Récupérer des informations (9) ............................................................................................................................. 67
5.5. Signaux et slots (9) .........................................................................................................................................................72
5.6. Plug-ins (2) ..................................................................................................................................................................... 83
5.7. Temps (6) ........................................................................................................................................................................85
5.8. Événements (1) ............................................................................................................................................................... 91
5.9. Ressources (1) .................................................................................................................................................................93
6. QtGui (38) ................................................................................................................................................................................95
6.1. Animations (2) .............................................................................................................................................................. 111
6.2. Graphics View (2) ........................................................................................................................................................ 117
6.3. Model View (4) ............................................................................................................................................................ 119
6.4. Assistants (7) ................................................................................................................................................................ 123
6.5. Style (5) ........................................................................................................................................................................ 129
6.6. Icônes (2) ...................................................................................................................................................................... 135
7. QtXml (4) ...............................................................................................................................................................................136
7.1. DOM (2) ....................................................................................................................................................................... 137
7.2. SAX (2) .........................................................................................................................................................................141
8. QNetwork (15) .......................................................................................................................................................................145
8.1. QHttp (5) .......................................................................................................................................................................149
8.2. Sockets (2) .................................................................................................................................................................... 158
8.3. Gestionnaire d'accès (6) ................................................................................................................................................160
9. Phonon (6) ............................................................................................................................................................................. 164
9.1. Généralités (4) ...............................................................................................................................................................165
9.2. Backends (2) ................................................................................................................................................................. 167
10. Intégration avec d'autres librairies (4) .................................................................................................................................168
10.1. boost.signals (4) .......................................................................................................................................................... 169
11. EDI (5) ................................................................................................................................................................................. 173
11.1. QtCreator (4) ...............................................................................................................................................................174
12. Les bibliothèques complémentaires (21) .............................................................................................................................176
12.1. Qwt (13) ......................................................................................................................................................................177
12.2. QCA (7) ...................................................................................................................................................................... 183

-3-
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sommaire > Introduction à Qt4


Quelle est la licence d'utilisation de Qt4 ?
Auteurs : Matthieu Brucher , Yan Verdavaine , Benjamin Poulain ,
Depuis la version majeure 4.5, Qt4 est distribué sous trois licences :

-4-
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

• commercial : vous permet de faire ce que vous voulez avec le code de Qt et votre code.
• GPL V3 : tout code développé avec la version GPL de Qt doit aussi être GPL. Tout le code doit donc être
accessible aux utilisateurs de l'application. C'est la licence généralement choisie pour les projets Open Source.
• LGPL v2.1 : similaire à la GPL, mais si Qt est lié dynamiquement à votre application, le code de votre
application peut être fermé/propriétaire. Les modifications sur les sources de Qt seront obligatoirement LGPL.
Avec cette licence, l'utilisateur doit avoir la possibilité de remplacer Qt par sa propre version. Cela n'est
généralement un problème que lorsque Qt est intégré directement dans un appareil (télévision, GPS, etc.).

lien : Les licences Qt sur le site de QtSoftware


lien : GPL
lien : LGPL

Où trouver la documentation de Qt ?
Auteurs : Alp Mestan ,
Nokia propose une documentation plus qu'exhaustive pour chacune des versions de Qt. Le sommaire de toutes ces
documentations se trouve ici : Online Reference Documentation

De plus, chaque version de Qt est distribuée avec un outil permettant de parcourir la documentation : Qt Assistant. La
version de la documentation accessible avec Qt Assistant correspond à la version de Qt avec laquelle il a été distribué.

Que sont les Qt Quarterly ?


Auteurs : Thibaut Cuvelier ,
Qt Quarterly est une revue électronique trimestrielle proposée par Nokia à destination des développeurs et utilisateurs
de Qt. Vous pouvez retrouver les articles sur le site de Nokia.

La rédaction Qt de Développez vous propose la traduction de certains articles, leur nombre augmentera régulièrement.

Ces articles sont écrits par des professionels de Qt, qui ont de l'expérience avec ce framework : ces sommités nous font
part de leur expérience dans le domaine, pour simplifier le développement et pour éviter des erreurs courantes.

Quels sont les chemins des en-têtes à inclure lors de la compilation ?


Auteurs : Matthieu Brucher , Alp Mestan , Benjamin Poulain ,
Tout d'abord, Qt4 propose 2 types d'en-têtes : les en-têtes standards avec un .h comme extension, et les autres, sans
extension.

Pour que la compilation se déroule correctement, il faut que le chemin vers les en-têtes de Qt soit inclus dans la liste des
dossiers à parcourir pour les en-têtes, mais aussi chacun des sous-dossiers des bibliothèques que vous utiliserez.

Enfin, il faut savoir que pour chaque classe de Qt, il existe un en tête qui porte le même nom que la classe. Si par exemple
vous utilisez QString, il faut un include de ce genre.

#include <QString>

-5-
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Par défaut, les fichiers d'en-tête se trouvent dans les frameworks sous Mac OS X (/Library/Frameworks), dans
les includes sous Linux (généralement dans /usr/include/qt4), et dans le repertoire où Qt est installé sous Windows
(généralement dans C:\Qt\4.x.x\include). Pour compiler une application Qt, vous pouvez utiliser qmake, qui définira
ces chemins pour vous.

Comment débuter avec Qt ?


Auteurs : Benjamin Poulain ,
Qt est un framework orienté objet qui se base sur le langage C++. Pour bien profiter de Qt, il vaut donc mieux
commencer par apprendre les bases de C++ et de la programmation orientée objet.

Sur ces bases, un bon départ est de lire (et appliquer !) les tutoriels Débuter dans la création d'interfaces graphiques
avec Qt 4 et Carnet d'adresses. Qt introduit de nombreux concepts pour faciliter la programmation graphique, et lire le
tutoriel peut vous être utile, même si vous avez déjà utilisé une bibliothèque graphique.

Pour essayer les exemples du tutoriel, il faut un environnement de développement configuré pour utiliser Qt. Le plus
simple pour commencer est d'utiliser le Qt SDK (Qt avec un EDI, QtCreator, et un compilateur, MinGW) ou d'installer
Qt et d'utiliser Monkey Studio ou QDevelop.

Lorsque vous avez acquis les concepts du tutoriel, vous pouvez continuer avec les exemples de Qt. Chaque version de
Qt est distribuée avec un logiciel nommé QtDemo, celui-ci est bourré d'exemple avec leur code source.

lien : Tutoriel : installez Qt sur Mac avec Xcode ou QtCreator


lien : Tutoriel : installez Qt 4.4.3 facilement et compilez vos applications

-6-
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sommaire > Généralités


Est-ce compliqué d'utiliser Qt 4 ?
Auteurs : Alp Mestan ,
En réalité, utiliser Qt est plus simple que ce que l'on pense. En effet, le code suivant affiche un bouton qui ferme
l'application lorsque l'on clique dessus, et pourtant il ne fait que 13 lignes.

// Nécessaire pour créer une application avec Qt


#include <QApplication>
// Nécessaire pour pouvoir créer un bouton
#include <QPushButton>

// La fonction main() habituelle


int main(int argc, char ** argv)
{
// Qt récupère les arguments passés au programme
QApplication app(argc, argv);
// on crée notre bouton, intitulé "Hello World"
QPushButton quit("Hello World!");
// on le redimensionne
quit.resize(300, 40);
// on change la police et la taille
quit.setFont(QFont("Arial", 18, QFont::Bold));
// on explique à Qt que l'application doit se terminer lors du clic
//sur le bouton créé précédemment
QObject::connect(&quit, SIGNAL(clicked()), &app, SLOT(quit()));
// on affiche le bouton
quit.show();
// on laisse Qt gérer le code de retour du programme
return app.exec();
}

Comme vous pouvez le voir, il est très simple de gérer ses composants. Pour en découvrir plus, il est bon de consulter
la documentation et les exemples de Nokia, ainsi que les tutoriels présents sur la rubrique Qt de Développez.com.

Que faudrait il connaitre au minimum du C++ pour bien utiliser Qt ?


Auteurs : Yan Verdavaine , Alp Mestan , Denys Bulant , Aurelien.Regat-Barrel , Benjamin Poulain , Thibaut Cuvelier ,
Pour vous aider, voici un petit récapitulatif des notions importantes du C++ utilisées dans Qt. Bien sûr, tout ceci n'est
qu'indicatif, et peut être discuté.

Fondements
• Programmation orientée objet en C++ (déclaration d'une classe ou structure, héritage, appel de fonction
membre...) ;
• Différence entre mémoire statique et dynamique (connaître la durée de vie des objets instanciés, et même
mieux : la maîtriser) ;
• Polymorphisme et surcharge d'opérateur ;
• Cast (transformation d'une pointeur sur QObject ou QWidget vers le type réel de l'objet) ;
• Templates (conteneurs de Qt, principalement) ;
• Anglais (pour parcourir la documentation officielle).

De préférence
• Operateurs binaires ~ ! | & (paramétrer certaines fonctionnalités grâce aux drapeaux, même si Qt fournit la
classe QFlags pour simplifier ce traitement) ;

-7-
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

• Itérateurs, en C++ ou en Java (parcours avancé sur des éléments). Qt fournit la méthode foreach, qui évite
l'utilisation des itérateurs, suffisante dans la plupart des cas.

Comment optimiser avant distribution ?


Auteurs : Benjamin Poulain ,
Avant de distribuer/déployer une application, il faut généralement l'optimiser. Un application plus rapide permet de :

• Avoir un avantage sur les applications concurrentes (en particulier les applications web) ;
• Diminuer la consommation énergétique (ce qui est particulièrement important si Qt est utilisé sur un
téléphone).

La première étape pour optimiser est de faire tourner l'application dans un profiler. Un profiler fait des statistiques
de l'utilisation du code et permet de trouver les branches et fonctions qui prennent le plus de temps à l'exécution. Il
existe de nombreux profiler pour C++ : Valgrind avec callgrind (Linux), Intel VTune (Linux et Windows), Instruments
(XCode, Mac OS X), Visual Studio Profiler (Windows).

La seconde étape est d'activer les optimisations à la compilation. Ces optimisations sont valables pour Qt comme pour
l'application, il faut donc recompiler les deux et pas seulement l'application. Il faut recompiler en mode release pour
que le code de débogage (QDebug, Q_ASSERT) ne soit pas inclus, ne pas inclure les symboles de débogage (retirer
l'option -g), et activer les optimisations (option -O2). Si le compilateur le permet, l'utilisation de PGO (Profile-Guided
Optimization) permet d'améliorer encore les performances.

Finalement, avec une licence commerciale ou pour un projet open-source, compiler statiquement améliore aussi les
performances.

lien : Quand et comment réaliser une compilation "statique"?

Comment connaître l'OS de l'utilisateur ?


Auteurs : Louis du Verdier ,
Qt permet à travers toutes ses fonctionnalités de pouvoir connaître le nom de l'OS de l'utilisateur du programme. Si
quelqu'un laisse ses sources à disponibilité publique, il pourra donc par exemple aviser pour l'ouverture d'un fichier
par l'explorateur pour tel type d'ouverture pour Mac et tel autre type pour les autres OS (car ce type de chose est
différent chez Mac, ce qui montre l'intérêt de la récupération du nom du système d'exploitation sur lequel a été lancé
le programme)...

La documentation regorge d'informations permettant de trouver ce nom. Par exemple, pour Mac, on y trouve
Q_WS_MAC et pour Windows, on y trouve Q_WS_WIN.

Mais comment exploiter ces résultats ? Eh bien, une condition de ce type fera parfaitement l'affaire !

#if defined(Q_WS_WIN)
// ...
#endif

Dans ce code, on dit : "Si Q_WS_WIN est défini, ..." ou tout simplement : "Si on tourne sous Windows actuellement, ...".

Voici un exemple vous permettant de récupérer l'OS utilisé et de l'indiquer à l'utilisateur dans une boîte de dialogue.

-8-
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

#include <QApplication>
#include <QtGui>

class FenPrincipale : public QMainWindow


{
Q_OBJECT
public:
FenPrincipale()
{
#if defined(Q_WS_WIN) // Si on est sous Windows
QMessageBox::information(NULL, "Nom de l'OS", "Vous tournez sous Windows !");
#endif
#if defined(Q_WS_QWS) // Si on est sous Embedded Linux
QMessageBox::information(NULL, "Nom de l'OS", "Vous tournez sous Embedded Linux !");
#endif
#if defined(Q_WS_MAC) // Si on est sous Mac
QMessageBox::information(NULL, "Nom de l'OS", "Vous tournez sous Mac !");
#endif
#if defined(Q_WS_X11) // Si on est sous X11
QMessageBox::information(NULL, "Nom de l'OS", "Vous tournez sous X11 !");
#endif
}
};

#include "main.moc"

int main(int argc, char *argv[])


{
QApplication app(argc, argv);
FenPrincipale fenetre;
fenetre.show();
exit(0);
}

-9-
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sommaire > Généralités > Mémoire


Comment Qt optimise-t-il les copies ?
Auteurs : Yan Verdavaine ,
Qt est basé sur une sémantique de copie. C'est à dire qu'elle utilise beaucoup la copie pour permettre de créer des
logiciels robuste et évite un bon nombre de bugs. Pour optimiser cela, Qt implémente le pattern COW (Copy on Write) :
la copie interne est réellement effectuée lors d'un accès en écriture sur un objet interne partagé d'une classe. Dit d'une
autre manière, Qt va partager en lecture un objet interne entre différent instances égaux d'une classe.

Le principe est le suivant :


1 Lors d'une copie, un objet interne est partagé.
2 Tant qu'aucune des instances ne modifie cette objet, il reste partagé.
3 Dès qu'une des instances modifie l'objet, cette instance va copier l'objet interne et appliquer la modification.

// s1 va créer un objet interne contenant "hello word"


QString s1 = "hello word";

// s2 va référencer le même objet interne que s1.


// Il n'y a pas eu de vraie copie.
QString s2 = s1;

// Accès en lecture au premier caractère => inutile de faire une copie


qDebug()<< s2[0];

// On veut modifier la première lettre de s2 :


// s2 créé un nouvel objet interne et copie le contenu.
// s1 et s2 n'utilisent plus le même objet interne
// s2 modifie la première lettre
s2[0] = 'b';

Remarque : ce pattern est thread safe dans l'implémentation Qt.

lien : Liste des classes Qt basées sur le COW


lien : Comment optimiser la copie de ses classes ?

Comment gérer la mémoire avec Qt ?


Auteurs : Benjamin Poulain ,
Qt est conçu de façon à rendre aisée la gestion de la mémoire. Il y a deux mécanismes pour y arriver : les types simples
et les hiérarchies.

Les objets simples, tel que les chaînes de caractères, conteneurs... peuvent être manipulés comme les types de bases, la
mémoire est nettoyée automatiquement par le destructeur.

QString getSiteName()
{
// pas de problème à l'allouer sur la pile
QString siteName = "Developpez.com";
// pas de problème à l'utiliser comme type de retour
return siteName;
}

- 10 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Ce type d'objet n'utilise en interne qu'un pointeur vers un délégué, ce qui veut dire que ces objets sont extrêmement
rapides à manipuler.

QRectF rect(0.0, 0.0, 50.0, 50.0);


// le constructeur par copie est rapide
QRectF rectClone = rect;
QRectF copy;
// l'affectation est tout aussi rapide
copy = rect;

Ce type d'objet est donc très facile à utiliser car on peut l'employer comme s'il s'agissait d'un type de base.

D'autres objets ont besoins d'une gestion de mémoire plus complexe car il faut contrôler précisément leur durée de
vie. Pour ces objets, Qt a introduit le mécanisme de hiérarchie d'objet, qui est disponible pour toutes les sous-classes
de QObject.

Les objets d'une hiérarchie peuvent avoir un objet parent, et des objets enfants (à ne pas confondre avec l'héritage, il
s'agit ici d'encapsulation). Lorsqu'un objet est détruit, tous ses objets enfants sont détruits aussi.

Le parent est précisé dans le constructeur des objets ou grâce à la méthode QObject::setParent().

QString giveString()
{
QObjet parent;
MyObjet *myObjet = new MyObject(parent);
myObjet->doSomeComputation();
return myObjet->getString();
}

Étonnamment, le code précédent n'a pas de fuite de mémoire. L'objet MyObjet, créé sur le tas, a, comme parent, le
QObject "parent". Lorsque parent arrive à la fin de la fonction giveString(), son destructeur se charge de supprimer
l'objet myObjet.

L'exemple précédent est artificiel, voyons un exemple plus réaliste.

void showMessage()
{
QDialog dialog;
QVBoxLayout *layout = new QVBoxLayout(&dialog);
QLabel *message = new QLabel("Cliquez sur le bouton");
layout->addWidget(message);
QButton *button = new QButton("Cliquez ici");
layout->addWidget(button);
dialog.exec();
}

- 11 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Quelle magie fait que ce code fonctionne ? Lorsqu'un widget est ajouté au layout, le layout le reparente automatiquement
avec son widget propriétaire (dialog dans ce cas-ci). Finalement, lorsque la fonction se termine, le destructeur de dialog
supprime tous les objets et nettoie la mémoire.

lien : Comment optimiser la copie de ses classes ?

Comment optimiser la copie de ses classes ?


Auteurs : Yan Verdavaine ,
Une grosse partie de Qt est basé sur le COW. Il permet ainsi d'utiliser ce pattern. Pour cela, il faut créer une classe qui
hérit" de QSharedData, et qui possède un constructeur, un constructeur par copie et un destructeur public. Cette classe
sera l'objet interne qui sera partagé. Elle possède un compteur de références thread safe et ne doit pas être directement
accédée. Sa vie sera gérée par d'autres classes.

Pour accéder à une instance de cette classe, deux choix sont possible :

• QSharedDataPointer : permet de partager implicitement un QSharedData. L'objet interne est partagé en


lecture. L'accès à l'objet en écriture va générer une copie de l'objet.
• QExplicitlySharedDataPointer : permet de partager explicitement un QSharedData. L'objet interne est partagé
en lecture/écriture. L'objet interne sera copié uniquement sur demande.

Ces deux classes sont des pointeurs intelligents spécialisés dans la manipulation des pointeurs sur QSharedData. Ils
implémentent donc la sémantique des pointeurs avec des accès const (lecture) et non const (écriture). Elles détruiront
le QSharedData une fois son compteur à zéro. Ces pointeurs intelligents possèdent deux fonctions qu'il est utile de
connaître :

• detach() : si le compteur de référence est supérieur à 1, le QSharedData sera copié ;


• reset() : initialise à null le pointeur intelligent.

Remarque : ces classes sont thread safe.

lien : Comment Qt optimise-t-il les copies ?


lien : Faq C++ : pointeurs intelligents
lien : Tutoriel : Pointeurs intelligents

- 12 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sommaire > Généralités > Déploiement


Comment déployer une application Qt sous Windows ?
Auteurs : François Jaffré ,
Si vous avez créé votre application à l'aide de Visual Studio et, par conséquent, utilisé le compilateur C++ de Microsoft,
il faut procéder de la manière suivante :

• Intaller le runtime VC, correspondant à la version de Visual Studio que vous utilisez, sur la machine cible ;
• Mettre dans le répertoire de votre exécutable les DLL de Qt, QtCore4.dll et QtGui4.dll ;
• Ajouter dans ce même répertoire les DLL correspondant aux autres modules de Qt (QtXml4.dll,
QtWebKit4.dll, QtSvg4.dll...), si votre exécutable les utilise ;
• Ajouter dans ce même répertoire les DLL correspondant aux librairies tierces, compléments de Qt (pour Qwt :
qwt5.dll ; pour QCA : qca2.dll...), si votre exécutable les utilise ;
• Ajouter le répertoire correspondant aux plug-ins que vous utilisez.

Si vous avez compilé votre application avec MinGW/GCC, procédez de la manière suivante :

• Ajouter la DLL du runtime de MinGW, mingwm10.dll, dans le repertoire de l'application ;


• Mettre dans le répertoire de votre exécutable les DLL de base de Qt, QtCore4.dll et QtGui4.dll ;
• De même, ajouter, dans ce même répertoire, les DLL correspondant aux modules de Qt (QtXml4.dll,
QtWebKit4.dll, QtSvg4.dll...), si votre exécutable les utilise ;
• Ajouter dans ce même répertoire les DLL correspondant aux librairies tierces, compléments de Qt (pour Qwt :
qwt5.dll ; pour QCA : qca2.dll...), si votre exécutable les utilise ;
• Ajouter le répertoire correspondant aux plug-ins que vous utilisez.

Au final, le répertoire d'une application Qt, utilisant, par exemple, les plug-ins MySQL, MNG, SVG et TIFF, ressemble
à ceci :

|App
\
-app.exe
-QtGui4.dll
-QtCore4.dll
-QtSql4.dll (module SQL)
-mingwm10.dll (si vous avez compilé avec MinGW)
\sqldrivers (répertoire des drivers pour QtSQL)
-qmysql.dll (driver MySQL)
-libmysql.dll (DLL nécessaire au plug-in du driver MySQL)
\imageformats (répertoire des plug-ins de traitement des formats d'image)
-qmng4.dll (MNG)
-qsvg4.dll (SVG)
-qtiff4.dll (TIFF)

Votre exécutable doit, dans tous les cas, être compilé en mode release.

Les DLL de Qt se trouvent le plus souvent sous Windows dans C:\Qt\4.x.x\bin. Prenez bien
les DLL correspondant à la version release de Qt, celles qui n'ont pas de d dans leur nom.
Par exemple, QtCore4.dll, la version release, et QtCored4.dll, la version debug.

Les répertoires contenant les plug-ins Qt se trouvent généralement dans C:\Qt\4.x.x\plugins.

- 13 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sommaire > Généralités > Contribuer


Comment contribuer aux projets Qt ?
Auteurs : Jonathan Courtois ,
Depuis la version 4.5 sortie en mars 2009, le framework Qt est passé en licence LGPL, ce qui a eu pour effet de permettre
à tout développeur d'y contribuer.

Pour cela, les développeurs de Qt utilisent le gestionnaire de versions Git, et, plus particulièrement, Gitorious, qui
héberge des projets utilisant git gratuitement. Il est également possible d'utiliser ce site pour vos propres projets.

La méthode pour contribuer est la suivante (l'utilisation du protocole Git ne sera pas détaillée, assez complexe et
nécessitant dédié).

• Allez à la page des projets Qt ;


• Choisissez le projet pour lequel vous voulez contribuer : le framework Qt, Qt Creator, Qt Jambi, Qt Mobility,
Qt Labs ou PySide ;
• Créez un compte sur le site Gitorious ;
• Clonez le répertoire source du projet que vous avez choisi ;
• Envoyez vos changements en local sur une branche de votre répertoire clone ;
• Créez une requête de fusion (merge) avec la branche principale ;
• Lisez et acceptez la licence de contribution de Qt ;
• Une équipe de développeurs Qt va alors analyser votre requête ;
• Si le code est approuvé, il sera ajouté à la branche principale de développement des projets Qt ; dans le cas
contraire, une requête échouée vous sera retourné avec le motif de l'échec (bugs, mauvaise lisibilité du code,
charte de programmation non respectée, etc.) ;
• En cas de succès, votre code sera alors disponible pour tous dans la prochaine version stable.

lien : Gitorious
lien : Qt sur Gitorious
lien : Documentation de Git

Comment contribuer à QtWebkit ?


Auteurs : Benjamin Poulain ,
QtWebkit est maintenu séparément du développement de Qt, il est développé directement dans le dépôt de Webkit.

Contribuer à QtWebkit est un peu différent de la manière de contribuer à Qt. Les contributions sont un peu plus
difficiles que pour Qt, car le dépôt est partagé avec Google et Apple.

Les étapes pour contribuer sont les suivantes :


• Obtenir QtWebkit depuis le dépôt de Webkit ou depuis le miroir sur Gitorious.
• Faire les changements voulus.
• Créer un rapport de bug.
• Les nouvelles fonctionnalités doivent aussi faire l'objet d'un rapport de bug.
• Si le patch concerne la partie Qt de Webkit (en particulier le code de WebKit/Qt), le mot-clé Qt devrait être
ajouté à la tâche.
• Ensuite, il faut soumettre le patch dans la tâche. Avant de générer le diff, il faut créer un Changelog des
modifications. Pour générer le changelog, il faut exécuter le script WebKitTools/Scripts/prepare-ChangeLog. Il
faut ensuite décrire les modifications dans le changelog créé.
• Soumettre le patch.

- 14 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

• Si le patch est prêt pour review, il faut choisir "?" dans le champ Review du patch.

Le wiki de Webkit fournit aussi quelques informations sur les contributions à Qt.

Les reviews sont rarement accordé la première fois. Les développeurs de Webkit sont extrêmement pointilleux sur :
• La présence de tests unitaires,
• Les conventions de codage, légèrement différentes des conventions de Qt.

lien : Comment contribuer aux projets Qt ?


lien : Dépôt de Webkit
lien : Gitorious
lien : Dépôt de Webkit sur Gitorious
lien : Rapport de bug et soumission des patchs
lien : Page du wiki sur le rapport de bug pour QtWebKit
lien : Tests unitaires
lien : Conventions de codage

- 15 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sommaire > Le contenu de Qt4


Que contient Qt4 ?
Auteurs : Matthieu Brucher ,
Qt4 a été découpé en plusieurs sous-bibliothèques, les modules, relativement indépendants les uns des autres.

• QtCore, qui contient les éléments essentiels du fonctionnement de toutes les bibliothèques Qt ;
• QtGui, qui contient les éléments essentiels graphiques pour les autres bibliothèques Qt ;
• QtNetwork, contenant des classes dédiées à la programmation réseau ;
• QtOpenGL, permettant le support d'OpenGL ;
• QtSql, permettant l'intégration de bases de données dans Qt ;
• QtSvg, permettant la lecture et l'écriture de fichiers SVG ;
• QtXml, contenant les classes utiles à la lecture et à l'écriture de fichiers XML ;
• QtDesigner, permettant l'extension de QtDesigner ;
• QtUiTools, permettant l'utilisations des fichier .ui de QtDesigner dans des applications ;
• QtAssistant, permettant d'utiliser le système d'aide de Qt ;
• Qt3Support, permettant de réutiliser presque de manière transparente les anciennes classes de Qt3 ;
• QtTest, contenant des outils permettant de réaliser des tests unitaires.

Chaque bibliothèque peut être ajoutée ou retirée des projets Qt, sachant que QtCore et QtGui sont ajoutées par défaut.

lien : Les modules Qt dans l'aide

Comment utiliser les modules de Qt ?


Auteurs : Niak74 ,
Qt intègre par défaut les modules QtCore et QtGui à vos projets. Si vous souhaitez utiliser d'autres modules, éditez
votre fichier PRO et modifiez la variable QT. Vous pouvez aussi retirer volontairement le module QtGui lié par défaut
(dans le cas d'une application Qt).

# Ajouter le module SQL


QT += sql

# Retirer le module GUI


QT -= gui

Voici les modules de Qt ainsi que la valeur à ajouter à QT si vous les utilisez.

• core (inclus par défaut) : QtCore


• gui (inclus par défaut) : QtGui
• network : QtNetwork
• opengl : QtOpenGL
• phonon : Phonon
• sql : QtSql
• svg : QtSvg
• xml : QtXml
• webkit : QtWebkit
• qt3support : Qt3Support

Pour savoir quel module contient la classe Qt que vous souhaitez utiliser, reportez vous à la documentation officielle
Qt. Chaque classe possède un en-tête formaté de la manière suivante :

- 16 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Nom_de_la_classe Class Reference


Module_contenant_la_classe

- 17 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sommaire > La compilation

- 18 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sommaire > La compilation > Généralités sur la compilation


Comment compiler des projets utilisant Qt 4 ?
Auteurs : Alp Mestan ,
Les développeurs de Qt 4 proposent des outils très utiles qui facilitent la gestion de vos projets utilisant Qt 4. En effet, il
existe un outil permettant de transformer les fichiers du designer (.ui) en fichiers C++, un autre permettant de générer
le code nécessaire pour la création de widgets personnalisés...

Cependant, ils fournissent également un outil permettant de gérer automatiquement les fichiers du designer, les fichiers
dans lesquels vous définissez des widgets personnalisés, et même en réalité tout votre projet : qmake. Cet outil permet
de générer un fichier de projet .pro, de générer à partir de ce dernier les règles de compilation de votre projet, et bien
d'autres choses, comme la détection de votre compilateur, du répertoire d'installation de Qt 4...

Un tutoriel a été écrit pour présenter cet outil et décrire son utilisation : Compilation des projets Qt 4.

lien : Compilation des projets Qt 4

Comment avoir des classes utilisant Q_OBJECT sans .h ?


Auteurs : Yan Verdavaine ,
En C++, il peut être parfois intéressent de déclarer une classe directement dans un fichier d'implémentation (.cpp, .cxx,
.cc...). Seulement, certaines classes exploitées par Qt obligent les fichiers à passer par le moc.

Pour remédier à ce problème, il est tout à fait possible d'appliquer le moc sur ce fichier. En contre partie, il faut inclure
le fichier généré à la suite de la déclaration de la classe dans le .cpp.

Si vous utilisez qmake, il suffit, juste après la déclaration de la classe, d'inclure un fichier utilisant le nom du fichier
cpp suivi de l'extension .moc. Cette méthode est utilisée dans certains codes de la Q/R pour simplifier la compilation
de l'exemple à un seul fichier.

Fichier nommé test.cpp


...
class myTest : QObject
{
Q_OBJECT
...
};
#include "test.moc"
...

Comment compiler Qt ?
Auteurs : Thibaut Cuvelier ,
Avant de compiler Qt, vérifiez que des binaires ne sont pas déjà fournis sur Developpez.com.

Tout d'abord, pour une compilation simple, avec toutes les options par défaut, utilisez un de ces jeux de commandes.

Vous devez utiliser, sous Windows, un invite configuré pour votre compilateur (avec les variables %PATH%,
%INCLUDE% et %LIB% configurées), tel que l'Invite de commandes de Visual Studio 2002 / 2003 / 2005 / 2008,

- 19 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

disponible dans le menu Démarrer (sous 2000 / XP : Tous les programmes > Microsoft Visual Studio 2002 / 2003 / 2005 /
2008 > Visual Studio Tools ; sous Vista et Seven : utilisez la barre de recherche).

Pour Visual Studio


rem Version 9.0 :
set QMAKESPEC="win32-msvc2008"
rem Version 8.0 :
set QMAKESPEC="win32-msvc2005"
rem Version 7.1 :
set QMAKESPEC="win32-msvc2003"
rem Version 7.0 :
set QMAKESPEC="win32-msvc2002"
rem Versions 7.0+ :
set QMAKESPEC="win32-msvc.net"
rem Version 6.0 :
set QMAKESPEC="win32-msvc'

configure
nmake

Pour les autres compilateurs


configure
make

configure vous demandera si vous acceptez la licence de Qt : vous devez d'abord la lire (), puis l'accepter (y).

Si vous voulez personnaliser votre compilation (ajouter le support d'autres librairies comme OpenSSL, par exemple),
vous pouvez voir l'ensemble des drapeaux disponibles en utilisant cette commande.

Comment cross-compiler Qt ?
Auteurs : Thibaut Cuvelier ,
Il vous suffit de préciser le drapeau -xplatform lors de la configuration de Qt.

Celui-ci informera le compilateur que les binaires devront être exécutables sur cette plateforme, et que les outils doivent
se lancer sur la plateforme hôte (précisée éventuellement par le drapeau -platform).

Vous pouvez spécifier tous les autres drapeaux dont vous avez besoin.

Pour pouvoir cross-compiler Qt, vous devez disposer d'un cross-compilateur (par exemple,
GCC, ou l'un des cross-compilateurs fournis avec Visual Studio) !

Voici deux listes reprenant l'ensemble des plateformes supportées.


Supported Platforms

Cross-compilation de Qt4

Pour obtenir un compilateur, regardez l'article sur la cross-compilation avec GCC 4 sous Windows pour Linux

- 20 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

configure -h

Quand et comment réaliser une compilation "statique"?


Auteurs : Benjamin Poulain ,
Vous n'avez le droit de compiler Qt statiquement que si :

• Vous écrivez un logiciel open-source sous licence GPL, ou


• Vous avez une licence commerciale.

Si vous n'êtes pas dans un de ces deux cas, ne compilez pas statiquement votre application.

La LGPL ne change rien au problème : l'utilisateur doit pouvoir remplacer votre version de Qt par celle qu'il désire.
Si vous liez statiquement à Qt, l'utilisateur ne pourra pas remplacer Qt, et vous serez en infraction avec la licence.

Compiler statiquement une application permet de gagner légèrement en performance et de diminuer légèrement la
taille du package à distribuer. Il est rare de compiler statiquement pour GNU/Linux pour des raisons de performance
et de flexibilité.

Pour compiler statiquement, il faut une version de Qt compilée statiquement, il faut recompiler la bibliothèque avec
l'option -static. Ensuite, il faut compiler l'application elle-même statiquement. Si vous utilisez qmake, il suffit d'ajouter
la directive CONFIG += static au fichier de configuration (fichier .pro), de relancer qmake et de recompiler le projet.

Il reste le problème des plug-ins. Qt charge certaines fonctionnalités grâce à un système de plug-ins. Ce chargement
dynamique ne peut évidemment pas fonctionner en version statique. Pour utiliser un plug-in, il faut modifier
l'application pour le charger explicitement à la compilation. Ceci est fait à l'aide de la macro Q_IMPORT_PLUGIN().

#include <QApplication>
#include <QtPlugin>

Q_IMPORT_PLUGIN(qtaccessiblewidgets)
Q_IMPORT_PLUGIN(qjpeg)
Q_IMPORT_PLUGIN(qgif)

int main(int argc, char *argv[])


{
...

Le plug-in qtaccessiblewidgets permet d'utiliser les outils d'accessibilité avec l'application, il est recommandé de
toujours inclure ce plug-in.

Comment utiliser une bibliothèque externe dans mon projet ?


Auteurs : Niak74 ,
Utiliser une bilbiothèque (statique ou dynamique) dans un projet nécessite deux choses :

• Indiquer au compilateur où rechercher les fichiers d'en-tête relatifs à la bibliothèque pour avoir accès aux
fonctions qu'elle propose ;
• Indiquer au compilateur de lier la bilbiothèque à l'exécutable du projet.

Étape 1 : indiquer au compilateur le chemin des fichiers d'en-tête de la librairie externe

- 21 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

La manière classique est d'ajouter l'option de compilation suivante à l'appel de votre compilateur :

-I/chemin/des/en-têtes/de/la/bilbiothèque

Si vous utilisez un IDE, fouillez dans les propriétés de votre projet afin de lui indiquer où rechercher les fichiers d'en-
tête de votre bibliothèque.

Avec Qt, il faut ajouter une ligne au fichier de projet (.pro) :

INCLUDEPATH += /chemin/des/en-têtes/de/la/bilbiothèque

Vous pouvez dès à présent inclure dans votre code source des fichiers provenant du répertoire spécifié.

Étape 2 : Indiquer au compilateur de lier la bibliothèque à l'exécutable

Pour lier une librairie à l'exécutable d'un projet Qt, il est nécessaire de modifier le fichier de projet afin que le Makefile
généré par qmake tienne compte de cette bibliothèque.

Prenons l'exemple du fichier d'import de la bibliothèque libmaLibrairie.a localisée dans /chemin/de/la/lib/


libmaLibrairie.a.

La manière classique de linker (lier) une bibliothèque à un projet C/C++ est d'ajouter les options de compilation
suivantes lors de l'exécution du linker (ld, sous les systèmes GNU/Linux) :

-lmaLibrairie
-L/chemin/de/la/lib

On ne précise pas le préfixe (lib) ni l'extension (.a) du fichier d'import !

Sous Qt, il faut ajouter des lignes au fichier de projet :

LIBS += -lmaLibrairie
LIBS += -L/chemin/de/la/lib

Sous Windows, le caractère \ utilisé comme séparateur dans les chemins doit être échappé (par
exemple, C:\MonDossier devient c:\\MonDossier). De plus, l'espace dans un nom de dossier
peut entraîner des erreurs, indiquez-le dans ce cas entre guillemets (par exemple, C:\\Mon
Dossier devient "c:\\Mon Dossier").

Une fois le fichier de projet modifié, exécutez qmake pour mettre à jour les Makefile, puis make (ou nmake sous Visual
Studio) pour recompiler votre projet.

Quelles sont les dépendances de Qt ?


Auteurs : Thibaut Cuvelier ,
Qt est un framework très complet, il propose beaucoup de choses de lui-même. Cependant, très souvent, il n'est pas
utile de réinventer la roue : Qt, comme beaucoup d'autres, se base donc sur d'autres librairies, écrites par d'autres,
pour proposer certaines fonctionnalités. Voici ces librairies et leurs versions minimales, qui peuvent ajouter des
fonctionnalités à Qt. Elles doivent être activées dès la compilation ; on peut la demander grâce à des drapeaux passés
à configure.

- 22 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Général
• Support OpenSSL : OpenSSL (v0.9.8) ;
• Support DBus : DBus ;
• Support Direct3D (déprécié dès Qt 4.5) : DirectX SDK (v9) ;
• Support OpenGL : inclus dans l'OS.

Il est possible d'activer le support de Direct3D aussi pour MinGW.

Back-ends Phonon
• Back-end DirectX : DirectX SDK (v9) ;
• Back-end VLC : libvlc ;
• Back-end MPlayer : MPlayer ;

Il est possible d'activer le support de Direct3D aussi pour MinGW.

Les librairies nécessaires sont en général installées en même temps que le SGBD.

• Plug-in MySQL : MySQL 4 ;


• Plug-in Oracle : Oracle 9i ;
• Plug-in ODBC : livré avec Windows ; implémentation autre pour UNIX ;
• Plug-in PostgreSQL : PostgreSQL 7.3 ;
• Plug-in Sybase : FreeTDS, MS DB-Library, Sybase Open Client ;
• Plug-in DB2 : DB2 7.1 ;
• Plug-in SQLite : 2 et 3 (la dernière est livrée avec Qt) ;
• Plug-in Borland InterBase : InterBase ;
• Plug-in FireBird (IB Free) : FireBird 2.

Quels sont les compilateurs utilisables avec Qt ?


Auteurs : Jonathan Courtois ,
Si vous téléchargé le SDK de Qt à partir du site officiel, les sources sont déjà compilées pour la plateforme choisie à
l'aide du compilateur MinGW (portage de GCC pour Windows). Cependant, il est possible de compiler ces sources avec
d'autres compilateurs, notamment les compilateurs natifs de chaque plateforme (comme Visual C++ sous Windows).

Actuellement, voici l'ensemble des compilateurs supportés pour la version 4.5.3 de Qt, dans leur notation canonique :

Plateformes soutenues activement


aix-xlc, aix-xlc-64, hpux-acc, hpux-g++, hpux-g++-64, hpuxi-acc, qws/linux-arm-g++, qws/linux-x86-g++, linux-g+
+, linux-icc, linux-icc-32, linux-icc-64, macx-g++, macx-g++42, solaris-cc, solaris-g++, win32-g++, win32-icc, win32-
msvc2003, win32-msvc2005, win32-msvc2008, wince-msvc2005, wince-msvc2008

Platformes soutenues par la communauté Qt


darwin-g++, freebsd-g++, freebsd-g++34, freebsd-g++40, freebsd-icc, hpuxi-g++, linux-cxx, linux-ecc-64, linux-g++,
linux-kcc, linux-llvm, linux-lsb-g++, lynxos-g++, macx-llvm, netbsd-g++, openbsd-g++, qws/linux-g++

Platformes précédemment soutenues


irix-cc, irix-g++, win32-msvc, win32-msvc2002, win32-msvc.net

- 23 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Pour compiler les sources Qt avec les plateformes supportées, il est nécessaire que le compilateur soit installé sur votre
machine, que les variables permettant de le connaître soient définies dans l'instance de votre shell (invite de commande
sous Windows) et que vous ajoutiez l'argument -platform lors de l'appel à configure (configuration de la compilation),
suivi du compilateur sous la forme canonique (par exemple, $>configure -platform win32-msvc2008).

lien : Installation de Qt 4 sous Windows avec Dev-C++


lien : Installation de Qt 4 Open Source, avec le support pour MySQL, Firebird et OpenSSL sous Windows
lien : Cross-compilation de programme Qt4 de Linux vers Windows
lien : Cross-compilation de Qt4

- 24 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sommaire > La compilation > qmake


Comment ajouter une console à une application ?
Auteurs : Yan Verdavaine ,
Sous Windows, l'ajout d'une console pour un application peut être importante :

• Application en ligne de commande ;


• Visualisation des messages Qt ;
• Visualisation des sortie standard ;
• ...

Pour cela, il suffit d'ajouter cette ligne dans votre fichier de projet .pro :

CONFIG += console

Il peut aussi être intéressant de n'activer la console que pour la version debug. Il faut alors ajouter cette ligne à votre
fichier de projet .pro :

debug:CONFIG += console

Comment compiler un projet Qt dans un répertoire spécifique ?


Auteurs : Jonathan Courtois ,
Le fichier .pro de projet Qt permet de définir un certain nombre de variables qui influence la compilation réalisée par
qmake. Certaines de ces variables permettent de définir le répertoire de sortie des différents fichiers générés pendant
la phase de compilation.

DESTDIR : Fichiers de sortie


DESTDIR = ../bin

MOC_DIR : Fichiers générés par l'outil moc (un fichier par classe héritant de QObject)
MOC_DIR = ../tmp

OBJECTS_DIR : Fichiers objets intermédiaires du compilateur


OBJECTS_DIR = ../tmp

RCC_DIR : Fichiers générés par l'outil rcc (sources C++ contenant les données des ressources Qt)
RCC_DIR = ../resources

UI_DIR : Fichiers générés par l'outil uic (en-têtes C++ correspondant aux fichiers d'interface)
UI_DIR = ../ui

- 25 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sommaire > QtCore


Un new sans delete ?
Auteurs : Matthieu Brucher ,
Dans un code Qt4, on verra souvent un new sans delete associé.

En fait, si une nouvelle instance de QObject est créée et qu'on lui spécifie un parent - le premier argument du
constructeur -, c'est ce parent qui sera chargé de la destruction du fils.

La majorité des classes de Qt4 hérite plus ou moins directement de QObject, mais attention, ce n'est pas le cas de toutes.
L'indicateur est la possibilité de passer un objet parent au constructeur.

lien : Allouer sur le tas ou sur la pile des QObject et dérivés ?

Erreur d'édition des liens undefined reference to 'vtable for xxx' ?


Auteurs : Matthieu Brucher ,
Cette erreur se produit lorsque la partie QObject d'une classe n'a pas été ajoutée à l'édition des liens.

Lors de l'utilisation de la macro Q_OBJECT, on définit un certain nombre de méthodes et de variables statiques. Ces
méthodes et ces variables sont implémentées dans un fichier généré automatiquement par qmake à l'aide de l'outil moc.
Vous pouvez naturellement créer ce fichier manuellement et l'ajouter pour compilation et édition des liens.

lien : La classe QObject


lien : Les signaux et slots

Comment ouvrir une application à partir de Qt ?


Auteurs : Yan Verdavaine ,
Qt fournit la classe QProcess. Cette classe permet de contrôler l'exécution d'une application dans un nouveau process.
Il est ainsi possible de contrôler :

• les variables d'environnements par la méthode setEnvironement() ;


• le répertoire d'exécution par setWorkingDirectory() ;
• de lancer l'application par la fonction start().

La fonction start() crée un processus enfant (qui sera fermé si le processus parent est fermé) avec, pour paramètres :

• Le path de l'exécutable,
• La liste des paramètres d'entrée de l'exécutable,
• Un mode d'ouverture pour interagir avec l'application par le biais des entrées/sorties standards.

Cette classe possède d'autres fonctions pour lancer une application :

• QProcess::execute : équivalent à start(). Bloquante jusqu'à la fin de l'exécution de l'application lancée.


• QProcess::startDetached : permet de lancer une application dans un processus indépendant. Peut donner le PID
du process créé.

Il est bon de remarquer que ces fonctions :

- 26 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

• Ont des paramètres similaires à ceux de start() : le path de l'exécutable, et la liste des paramètres d'entrée de
l'exécutable ;
• Ne donnent pas de moyen pour interagir avec le process par le biais des entrées/sorties standards ;
• Ces deux fonctions sont des fonctions statiques et peuvent être appelées sans création d'un QProcess. Dans
ce cas, les variables d'environnement et le répertoire d'exécution seront les mêmes que ceux de l'application
courante.

Exemple utilisant QProcess::startDetached


#include <QtGui>

class MyQPushButton : public QPushButton


{
public :
// créateur.
// text : texte du bouton
// exe : commande à exécuter lors de l'appui.
MyQPushButton(const QString & text,const QString & exe, QWidget * parent = 0)
: QPushButton (text,parent),
m_exe(exe)
{
resize(75, 30);
setFont(QFont("Times", 18, QFont::Bold));
};
virtual void mouseReleaseEvent ( QMouseEvent * event )
{
// Lance la commande dans un processus indépendant
QProcess::startDetached (m_exe);
}

private :
QString m_exe;

};

int main(int argc, char* argv[])


{
QApplication app(argc, argv);
QWidget w;
QVBoxLayout vl(&w);
// bouton : ouvre grâce au CMD la page vers DVP/Qt
MyQPushButton bouton1("Ouvrir DVP / Qt","cmd /c start http://qt.developpez.com/",&w);

// bouton : lance notepad


MyQPushButton bouton2("Ouvrir notepad","notepad",&w);

// bouton : lance invite de commande


MyQPushButton bouton3("Ouvrir invite de commande","cmd" ,&w);
vl.addWidget(&bouton1);
vl.addWidget(&bouton2);
vl.addWidget(&bouton3);
w.show();
return app.exec();
}

Comment interagir avec une application lancée par un QProcess?


Auteurs : Yan Verdavaine ,
QProcess permet de lancer des applications externes (Comment ouvrir une application à partir de Qt ?). Elle permet
surtout d'interagir avec l'application à la manière d'un pipe au travers des entrées/sorties standards de l'application.

- 27 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Ainsi le troisième paramètre de la fonction start permet de spécifier quel type d'interaction on veut utiliser (par défaut,
les deux types sont activés) :

• Mode read : récupération de la sortie standard (stdout) et d'erreur (stderr) ;


• Mode write : écriture sur l'entrée standard de l'application (stdin).

QProcess utilise les méthodes définies par QIODevice pour ces interactions. Pour la récupération des sorties, il faut
faire attention au channel que l'on est en train de lire.

• pour la sortie standard il faut utiliser : QProcess::StandardOutput


• pour la sortie d'erreur il faut utiliser : QProcess::StandardError

De plus QProcess fournit deux signaux intéressants, qui indiquent si des données venant d'une des sorties sont arrivées.

• readyReadStandardOutput () : des données provenant de la sortie standards sont prêtes à être traitées
• readyReadStandardError () : des données provenant de la sortie d'erreur sont prêtes à être traitées

Ces interactions sont aussi possibles à l'aide de fichiers :

• setStandardErrorFile : fichier où l'on récupère la sortie d'erreur de l'application lancée ;


• setStandardOutput : fichier où l'on récupère la sortie standard de l'application lancée ;
• setStandardInputFile : fichier contenant les données à envoyer sur l'entrée standard de l'application lancée.

Sous Windows XP, un programme lisant l'entrée standard (stdin) en parallèle de son IHM,
peut se bloquer lorsqu'il est exécuté en process enfant. Ce bug est normalement corrigé sous
vista.

lien : Comment ouvrir une application à partir de Qt ?


TestQProcess

Comment interagir avec les applications associées par défaut ?


Auteurs : Yan Verdavaine , Denys Bulant ,
Qt fournit la classe QDesktopServices et en particulier la fonction statique QDesktopServices::openUrl, qui permet
d'interagir avec les applications associées par défaut. Elle peut être étendue si nécessaire pour ajouter ses propres
handlers pour un schéma donné.

#include <QtGui>

class MyQPushButton : public QPushButton


{
public :
// créateur.
// text : texte du bouton
// exe : commande à exécuter lors de l'appui
MyQPushButton(const QString & text,const QString & url, QWidget * parent = 0)
: QPushButton (text,parent) , m_url(url)
{
resize(75, 30);
setFont(QFont("Times", 18, QFont::Bold));
};
virtual void mouseReleaseEvent ( QMouseEvent * event )
{
QDesktopServices::openUrl(m_url);

- 28 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

private :
QString m_url;

};

int main(int argc, char* argv[])


{
QApplication app(argc, argv);
QWidget w;

// Action : ouvre l'URL vers DVP /Qt


MyQPushButton bouton1(" Ouvrir DVP / Qt","http://qt.developpez.com",&w);
// Action : ouvre le fichier texte. /!\ ce fichier doit exister
MyQPushButton bouton2("Ouvrir fichier txt","c:/test.txt",&w);
// Action : ouvre l'édition d'un mail avec adresse et sujet remplis
MyQPushButton bouton3("Envoyer mail","mailto:qt@dvp.com?subject=test envoie mail" ,&w);

QVBoxLayout vl(&w);
vl.addWidget(&bouton1);
vl.addWidget(&bouton2);
vl.addWidget(&bouton3);
w.show();
return app.exec();
}

Comment charger et utiliser dynamiquement une .dll, .so avec Qt ?


Auteurs : Denys Bulant ,
Qt fournit la classe QLibrary permettant de charger de façon multi-plateformes une bibliothèque dynamique, ainsi que
d'en récupérer des pointeurs vers les fonctions exportées.

Après avoir créé un objet de ce type, il faut spécifier le nom de la bibliothèque dynamique à associer sans préciser
l'extension (ce n'est plus multi-plateformes, sinon). Il suffit ensuite d'appeler resolve() en fournissant le nom du symbole
à trouver. Il est retourné en tant que void*, donc un cast sera bien évidemment nécessaire. Sont aussi fournies des
fonctions statiques évitant l'instanciation dans le cas où l'on ne voudrait récupérer qu'un symbole.

Par exemple, admettons qu'une fonction d'une bibliothèque permette de compter le nombre de lettres dans un mot.

// définition du type de fonction


typedef int (*StringLength)(char*);
// création d'un objet QLibrary lié à string_util (.dll, .so ou autre)
QLibrary lib("string_util");
// récupération d'un pointeur sur notre fonction partagée
StringLength strLength = (StringLength)lib.resolve("strlen");
if(strLength)
// devrait renvoyer 9... si tout va bien ;)
strLength("QLibrary");

Comment récupérer les arguments envoyés par la fonction main ?


Auteurs : Louis du Verdier ,
Dans les années 1980 à 1990 (aucune information ne précise la date exacte), la fonction main() ne renvoyait rien, elle
était donc de type void. Plus récemment, des améliorations de cette fonction ont introduit les arguments, qui sont, en
fait, dans la norme actuelle, int argc et char *argv[]. Ces arguments sont complémentaires : char *argv[] représente un

- 29 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

tableau de pointeurs de taille donnée par int argc. Sur la plupart des systèmes d'exploitation, le tout sert par exemple à
retrouver le chemin du programme lancé (avec argv[0]), ou encore par exemple à retrouver un fichier par lequel s'est
ouvert le programme (argc serait donc supérieur à 1).

Quel rapport avec Qt ? Eh bien, la bibliothèque permet de récupérer les arguments à l'aide de la fonction
QCoreApplication::arguments. La récupération sert, par exemple, à récupérer le chemin d'un éventuel fichier ouvert
par clic sur l'icône de celui-ci.

QStringList args = QCoreApplication::arguments();


QString nom_fichier = args[1];

Note : Lors de la déclaration de la fonction main(), il faut mettre les arguments pour que ce qui est donné marche, c'est
à dire utiliser un début de code comme celui-ci pour la fonction main :

int main (int argc, char *argv[])


{
QApplication app(argc,argv)
// Suite du code
}

Remarque : En règle générale, le premier élément correspond au nom de l'exécutable. Suivant la plateforme et le mode
d'exécution, cet élément peut aussi contenir le chemin relatif ou le chemin absolu de l'exécutable concaténé avec son nom.

Voici un exemple permettant de clore.

const QStringList args = QCoreApplication::arguments();


// Si le programme a été ouvert par le biais d'un fichier
if(args.count() > 1)
{
// On récupère le chemin du fichier...
QString nom_fichier = args[1];
// ... et on appelle une éventuelle fonction de lecture
lireFichier(nom_fichier, this);
}
// ...

Attention : Sous Mac OS X, le double-clic sur un fichier ne sera pas renseigné dans les arguments, contrairement à
Windows et Linux. Pour cela il faut utiliser QFileOpenEvent.

Comment empêcher de lancer plusieurs instances d'un programme ?


Auteurs : François Jaffré ,
Qt fournit, à partir sa version 4.4, la classe QSharedMemory. Celle-ci permet la création de zone de memoires partagées
entre plusieurs applications. C'est en créant une zone mémoire partagée unique à notre application et en vérifiant au
début du programme si celle-ci existe déjà que nous allons savoir si notre application est déja lancée.

#include <QSharedMemory>
#include <QPushButton>
#include <QMessageBox>

int main(int argc, char *argv[])


{
QApplication a(argc, argv);

- 30 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

/* Création de la zone de mémoire partagé identifiée par une chaine de cractère.


* On utilisera un GUID pour avoir un identifiant unique pour qu'il n'y ait pas de conflit
* possible avec d'autres applications */
QSharedMemory sharedMemory("{69B55631-A712-4d8c-8852-A8ED297EF439}");

// On vérifie à la création de cette zone mémoire si celle-ci existe


if(sharedMemory.create(sizeof(int))==false)
{
// Utilisation d'une QMessageBox pour prévenir l'utilisateur que le programme est déjà lancé
QMessageBox msgBox;
msgBox.setText("L'application est déjà lancée");
msgBox.exec();
return 1; // On ferme l'application
}

QPushButton button("Hello Qt");


button.show();
return a.exec();
}

Comment lire et écrire dans un fichier INI ?


Auteurs : François Jaffré ,
Qt grâce à la classe QSettings permet de facilement manipuler des fichiers INI à l'aide des méthodes suivantes.

• void QSettings ::beginGroup (const QString & prefix) : créer un groupe ;


• void QSettings ::endGroup() : fermer le groupe courant ;
• void QSettings ::setValue (const QString & key, const QVariant & value) : créer une clef et lui adresser la
valeur donnée ; si la clef existe déjà, seule la clef sera mise à jour ;
• QVariant QSettings ::value (const QString & key, const QVariant & defaultValue = QVariant()) const :
Retourne la valeur correspondant à la clef passée en paramètre ; si cette clef n'existe pas, elle retourne la valeur
par défaut précisée en paramètre (defaultValue).

Voici un fichier INI.

[EquipeQt]
membre1=dourouc05
membre2=zAmnellL
membre3=IrmatDen

[ModerateursQt]
moderateur1=yan
moderateur2=superjaja

Voici comment on pourrait l'écrire.

// Création du fichier en précisant que l'on travaille avec un fichier de format INI.
QSettings settings("Developpez.ini", QSettings::IniFormat);

// Création du groupe [EquipeQt]


settings.beginGroup("EquipeQt");

// Création des différentes clefs et valeurs correspondantes


settings.setValue("membre1", "dourouc05");
settings.setValue("membre2", "zAmnellL");
settings.setValue("membre3", "IrmatDen");

// On ferme le groupe [EquipeQt]


settings.endGroup();

- 31 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

// Création du groupe [ModerateursQt]


settings.beginGroup("ModerateursQt");

// Création des différentes clefs et valeurs correspondantes


settings.setValue("moderateur1", "yan");
settings.setValue("moderateur2", "superjaja");

// On ferme le groupe [ModerateursQt]


settings.endGroup();

Voici comment on pourrait le lire.

// Ouverture du fichier INI


QSettings settings("Developpez.ini", QSettings::IniFormat);

// On récupère la valeur de membre1 du groupe [EquipeQt]


QString membre1 = settings.value("EquipeQt/membre1","Developpez").toString();
//membre1 == "dourouc05"

// On souhaite récuperer la clé membre4 du groupe [EquipeQt].


// Celui-ci n'existant pas c'est la valeur par default qui est retou_r_né.
QString defaultValue = settings.value("EquipeQt/membre4","Developpez")
.toString();
// defaultValue == "Developpez"

// On récupère la valeur du moderateur2 dans le groupe [ModerateursQt]


QString moderateur2 = settings.value("ModerateursQt/moderateur2","developpez")
.toString();
// moderateur2 == "superjaja"

Problèmes de traduction ?
Auteurs : Thibaut Cuvelier ,
Si vous avez des problèmes avec la traduction de votre application, vous pouvez vérifier ces quelques points.

1 Les chaînes sont-elles bien toutes entourées de tr() ?


2 Une variable serait-elle passée en paramètre de tr() ?
3 QT_TR_NOOP() serait-elle utilisée sans tr() ?
4 La classe à traduire hérite-t-elle bien de QObject ?
5 La classe à traduire appelle-t-elle la macro Q_OBJECT ?
6 Avez-vous installé le QTranslator ?
7 Avez-vous installé le QTranslator après avoir créé la fenêtre ?

lien : Qt Quarterly, Issue 3 : le chef suédois

Comment calculer un hash cryptographique de données ?


Auteurs : Thibaut Cuvelier ,
Pour ce faire, Qt 4.3 et suivants nous proposent la classe QCryptographicHash. Elle peut hasher n'importe quel
QByteArray avec les algorithme MD4, MD5 et SHA1. Seul le dernier est encore un peu sécurisé, mais c'est le plus lent.

Une collision, c'est deux données qui ont le même hash. Le temps qu'il faut pour trouver une collision détermine la
sécurité d'un algorithme de hashage. On peut calculer des collisions pour les deux premiers en moins d'une minute sur
un ordinateur moyen, contrairement aux 235 opérations requises pour SHA1 (34 359 738 368 opérations, précisément).
Chercher un moyen de trouver des collisions s'appelle la cryptanalyse

- 32 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Cependant, pour des besoins évolués (système banquaire, authentification sur un site), SHA1 ne convient plus, et doit
être remplacé par un algorithme plus performant, comme Whirlpool ou RipeMD-160, pour lesquels on ne connaît pas
encore de méthode pour trouver des collisions.

Qt ne supporte pas nativement d'autres algorithmes de hashage. Pour pallier ce manque, la communauté fournit QCA
(Qt Cryptographic Architecture). Cette bibliothèque se base sur Qt, et lui fournit moult autres fonctionnalités orientées
vers la sécurité.

Tous les algorithmes de hashage seront, un jour ou l'autre, cryptanalysés, et on pourra trouver assez facilement des
collisions avec un ordinateur moyen. C'est pour ça que, sans cesse, des commités cherchent les failles, et développent
de nouveaux algorithmes.

On peut utiliser cette classe de manière statique, sans instancier d'objet. Pour cela, on peut utiliser la méthode hash().
Voici son prototype.

QByteArray QCryptographicHash::hash ( const QByteArray & data, Algorithm method )

Algorithm est une énumération, que voici.

enum Algorithm { Md4, Md5, Sha1 }

Un exemple d'utilisation statique


QByteArray data ("Some data to hash");
QByteArray result ("");

result = QCryptographicHash::hash ( data, QCryptographicHash::Sha1 );

On peut aussi instancier l'objet, si on ne peut pas préciser toutes les données d'un seul coup.

On précise l'algorithme de hashage lors de l'instanciation de l'objet.

Pour ajouter des données à hasher, les méthodes addData() doivent être utilisées. Voici leurs prototypes.

void QCryptographicHash::addData ( const char * data, int length )


void QCryptographicHash::addData ( const QByteArray & data )

La méthode result() permet de récupérer le hash.

Un exemple d'utilisation dynamique


QByteArray data ("Some data to hash");
QByteArray oData ("Other data that will be hashed");
QByteArray result ("");
QCryptographicHash hasher (QCryptographicHash::Sha1);

hash- addData (data) ;


hash->addData ( oData->data(), oData->size() );
result = hash->result();

lien : Qu'est-ce que QCA ?

Comment imprimer avec Qt ?


Auteurs : Shugo78 ,
L'impression avec Qt est a peu prés équivalente au dessin sur un QWidget ou QImage. Il y a plusieurs étapes :

- 33 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

1 Créer un QPrinter comme périphérique de dessin ;


2 Ouvrir un QPrintDialog pour que l'utilisateur choisisse une imprimante et certaines options ;
3 Créer un QPainter pour agir sur le périphérique de dessin ;
4 Dessiner une page avec le QPainter ;
5 Changer de page avec QPrinter::newPage() ;
6 Recommencer les 2 étape précédentes jusqu'à que tout soit imprimé.

Sous Windows et Mac, QPrinter utilise les pilotes d'imprimante systèmes. Sous UNIX, il créé un PostScript
qu'il envoie à lp ou lpr (vous pouvez définir le programme auquel envoyer le PostScript avec la fonction
QPrinter::setPrintProgram()). QPrinter peut aussi être utilisé pour imprimé un fichier PDF en appelant
setOutputFormat(QPrinter::pdfFormat).

void printImage (const QImage &image)


{
QPrintDialog printDialog (&printer, this)
if (printDialog.exec())
{
QPainter painter (&printer);
QRect rect = painter.viewport ()
QSize size = image.size ();
size.scale (rect.size (), Qt::KeepAspectRatio);
painter.setViewport (rect.x (), rect.y (), size.width (), size.height ());
painter.setWindow (image.rect ());
painter.drawImage (0, 0, image);
}
}

Quels sont les pointeurs intelligents de Qt ?


Auteurs : Thibaut Cuvelier ,
Qt est extrêmement bien fourni en classes de pointeurs intelligents :

• QPointer (4.0) ;
• QSharedDataPointer (4.0) ;
• QExplicitlySharedDataPointer (4.3) ;
• QSharedPointer (4.5) ;
• QWeakPointer (4.5) ;
• QScopedPointer (4.6).

Chacun de ces pointeurs a un signification particulière, un emploi particulier. Avant d'aller plus en avant, il faut savoir
ce qui distingue les pointeurs intelligents, mais aussi à quoi ils servent.

Un pointeur intelligent permet de garder une référence à un objet, en s'assurant qu'il sera détruit à un certain moment.
Ils peuvent être utilisés par plusieurs objets en même temps, pour, par exemple, éviter d'utiliser trop de mémoire.

Principalement, ils peuvent partager des données ou un pointeur sur les données. Un pointeur intelligent pourrait donc
contenir un pointeur ? Oui : cela peut être utile lorsqu'un objet est partagé par plusieurs objets. Ainsi, l'objet référencé
n'est stocké qu'une fois en mémoire.

Ensuite, leur référence peut être légère ou forte. La référence forte implique que l'objet ne soit pas détruit, cela est
garantit par le pointeur intelligent. Tant qu'il existe, l'objet existe. Tandis qu'un pointeur à référence légère (weak
pointer) ne peut le garantir : il faut s'assurer qu'il ne sera pas détruit par d'autres moyens.

QPointer est un pointeur intelligent assent lent, c'est pour cela qu'on lui préfère de loin QWeakPointer.

- 34 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Il ne reste donc que 4 pointeurs intelligents, correspondant aux 4 combinaisons possibles des caractéristiques présentées

Classe Description
QSharedDataPointer & Partage de données (implicite et explicite)
QExplicitelySharedDataPointer
QSharedPointer Partage à comptage de référence de
pointeurs à référence forte
QWeakPointer Partage à comptage de référence de
pointeurs à référence faible
QScopedPointer & QScopedArrayPointer Emballage sans comptage de référence de
pointeurs à référence forte

lien : Comment optimiser la copie de ses classes ?


lien : Qu'est-ce qu'un pointeur intelligent ?
lien : Les pointeurs intelligents de Qt
lien : Pointeurs intelligents

Comment accéder à la base de registre Windows ?


Auteurs : François Jaffré ,
La base de registre est très importante pour Windows car elle contient les données de configuration du système
d'exploitation et des logiciels qui y sont installés. De même, elle sert énormément pour la configuration et l'initialisation
des programmes. Par exemple, les clés situées dans la clé Run, elle-même située dans HKEY_CURRENT_USER,
provoquent une exécution automatique au démarrage d'applications lors de l'ouverture d'une session. Qt permet de
facilement lire et écrire dans la base de registre de Windows à l'aide de la classe QSettings.

//Création d'une nouvelle clé nommée "Developpez" dans HKEY_CURRENT_USER


QSettings settings("HKEY_CURRENT_USER\\Developpez",QSettings::NativeFormat);

//Création de nouvelles clés avec leurs valeurs correspondantes dans "HKEY_CURRENT_USER\\Developpez"


settings.setValue("Moderateur1", "yan");
settings.setValue("Moderateur2", "superjaja");
settings.setValue("ResponsableQt", "dourouc05");

//Lecture de la valeur moderateur1


QString value = settings.value("Moderateur1").toString(); //value == "yan"

//Lecture de toutes les clés contenues dans "HKEY_CURRENT_USER\\Developpez"


foreach(const QString& str,settings.allKeys())
{
//str == Moderateur1, Moderateur2 puis ResponsableQt
qDebug() << str;
}

Que dois-je savoir sur les delegates ?


Auteurs : Louis du Verdier ,
Pour pouvoir intégrer un delegate dans une vue, il faut tout d'abord sous-classer QItemDelegate (ou bien
QAbstractItemDelegate), puis redéfinir sa fonction paint(). Une fois cela fait, il ne reste plus qu'à intégrer une instance
de la classe créée dans la vue en question par le biais d'une des fonctions suivantes, fournies par QAbstractItemView,
donc disponibles pour QTreeView, QListView, etc.

- 35 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

QAbstractItemView est une classe très utile car elle propose des méthodes permettant d'afficher des éléments dans
des modèles. Elle permet aussi de modifier leurs propriétés par le biais du modèle conteneur, ce qui la rend plutôt
attrayante. Passer par QItemDelegate pour réaliser des delegates de simples widgets permet à ces derniers de
bénéficier de possibilités plus vastes que celles qui sont proposées par QAbstractItemView. Quant à elle, la classe
QStyledItemDelegate est recommandée lors de la création de delegates personnalisés ou bien lors de l'utilisation de
feuilles de style.

La méthode sizeHint() est une méthode très utile dans le sens où elle permet de récupérer la taille que devrait avoir le
delegate. C'est pour cela qu'il est possible de la réimplémenter.

La fonction paint() est sans doute la méthode la plus importante de celles qui sont disponibles pour les delegates. En
effet, c'est elle qui permet de leur concevoir un rendu graphique. Si vous souhaitez offrir un rendu personnalisé à votre
delegate, c'est cette méthode que vous devrez réimplémenter.

Exemple simple d'intégration d'une barre de progression dans un QTreeView


#include <QApplication>
#include <QtGui>

class Delegate : public QItemDelegate


{
Q_OBJECT

public:
inline void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex
&index) const
{
// Création d'un QStyleOptionProgressBar qui permettra de dessiner notre barre de
progression :
QStyleOptionProgressBar progressBar;

progressBar.state = QStyle::State_Enabled;
progressBar.direction = QApplication::layoutDirection();
progressBar.fontMetrics = QApplication::fontMetrics();
progressBar.rect = option.rect;
progressBar.maximum = 100;
progressBar.minimum = 0;

// Gestion de la progression :
int progress = index.data().toInt();
progress = (progress < progressBar.minimum) ? progressBar.minimum : progress;
progress = (progress > progressBar.maximum) ? progressBar.maximum : progress;
progressBar.progress = progress;

// Gestion du texte :
progressBar.text = QString::number(progressBar.progress) + "%";
progressBar.textAlignment = Qt::AlignCenter;
progressBar.textVisible = true;

// Affichage de la barre de progression à l'aide du style de l'application :


QApplication::style()->drawControl(QStyle::CE_ProgressBar, &progressBar, painter);
}
};

#include "main.moc"

int main(int argc, char *argv[])


{
QApplication app(argc, argv);

QStandardItemModel *model = new QStandardItemModel(6, 2);


QTreeView *view = new QTreeView;
view->header()->setVisible(false);
view->setModel(model);

- 36 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Exemple simple d'intégration d'une barre de progression dans un QTreeView


// Utilisation de la fonction setItemDelegateForColumn() :
view->setItemDelegateForColumn(0, new Delegate);

for(int i = 0; i <= 5; ++i)


{
model->setData(model->index(i, 0), i);
model->setData(model->index(i, 1), "Texte");
}

view->show();

return app.exec();
}

- 37 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sommaire > QtCore > QObject


Allouer sur le tas ou sur la pile des QObject et dérivés ?
Auteurs : Matthieu Brucher , Benjamin Poulain ,
Chaque QObject contient une liste des pointeurs vers les QObject fils. Cette liste permet d'effacer automatiquement
les objets fils de cette liste.

Cette liste implique que les objets fils héritant de QObject devraient être alloués sur le tas et non la pile. A priori,
le code d'effacement est fait de telle sorte qu'il ne devrait pas y avoir de problème en allouant un objet sur la pile
car la destruction d'un objet entraîne sa suppression dans la liste des parents. En revanche, effacer manuellement ou
automatiquement par destruction dans la pile les objets fils peut entraîner un surcoût. Enfin, étant utilisé avec une
sémantique de pointeurs, il vaut mieux utiliser les pointeurs.

{ QObject parent;
QObject *enfant = new QObject(&parent);
}
// enfant est correctement supprimé de la mémoire par parent

De même, une instance héritée de QObject ne peut appartenir à deux QObject.

QObject *parent = new QObject;


QObject *enfant = new QObject(parent);

QObject autreParent;
enfant->setParent(&autreParent); // change le parent de enfant

delete parent;
// enfant n'est pas supprimé car parent ne "possède" plus enfant

La relation parent-enfant peut poser problème lorsque les QObject sont alloués sur la pile. Lorsqu'un objet est alloué
sur la pile, et a un parent, le parent pourrait appeler delete sur l'objet qui est sur la pile.

{
// !!! exemple de ce qu'il NE faut PAS faire, ne pas recopier !
QPushButton button("button");
QWidget widget;
button.setParent(&widget);
} // crash ici

// lorsque widget est détruit à la fin du scope, il supprime button à l'aide de delete.
// button avait été aloué sur la pile

lien : QObject
lien : Le modèle QObject

Héritage multiple avec QObject ?


Auteurs : Matthieu Brucher ,
L'héritage multiple de QObject n'est pas possible. En effet, l'architecture de Qt - les méta objets - rend la chose
impossible.

- 38 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Lorsque vous faites un héritage multiple, mettez en premier la classe héritant de QObject.

Peut-on utiliser des pointeurs intelligents sans danger avec des QObject ?
Auteurs : Aurelien.Regat-Barrel ,
QObject (et toutes les classes qui en dérivent) ne se marrient pas très bien avec les pointeurs intelligents classiques du C
++, tels que auto_ptr ou shared_ptr. Comme expliqué dans la question Un new sans delete ?, Qt implémente via QObject
un mécanisme de gestion de la mémoire dont le principe est qu'un QObject parent détruise automatiquement tous ses
objets QObject enfants.

Ce mécanisme est fort pratique et permet de grandement simplifier la gestion de la mémoire. Cependant, il entre
en conflit avec tout autre mécanisme de libération de la mémoire tel que ceux implémentés au moyen de pointeurs
intelligents.

En effet, si vous déclarez un pointeur intelligent sur une instance de QObject, ce dernier aura en charge la destruction
de cette instance. Si par malheur votre QObject se trouve être l'enfant d'un autre QObject, et que ce parent vient à
être détruit, votre instance sera elle aussi automatiquement détruite, alors que votre pointeur intelligent continuera de
pointer vers elle ! Et quand votre pointeur intelligent estimera qu'il est temps de la détruire, il effectuera un appel à
delete sur un objet déjà détruit (double utilisation de delete) avec toutes les conséquences fâcheuses que l'on connaît.

À noter que spécifier un parent nul au moment de la construction de votre QObject ne vous garantit pas pour autant
que ce dernier ne sera pas par la suite reparenté via la fonction setParent(), chose qui se produit assez régulièrement
entre objets graphiques (QWidget).

En conséquence, il est déconseillé d'utiliser des pointeurs intelligents sur des objets de type QObject. Si jamais vous
devez néanmoins y avoir recours, vous devez protéger votre instance d'une double deletion au moyen d'un guarded
pointer (QPointer en Qt 4, ou QGuardedPtr en Qt 3), comme dans l'exemple suivant.

shared_ptr<QPointer<QWidget> > ptr( new QWidget() );

La particularité d'un guarded pointer est qu'il est automatiquement mis à zéro si l'instance associée est détruite. Ainsi,
dans cet exemple, quand shared_ptr effectuera un appel à delete sur une instance déjà détruite, cela reviendra à effectuer
un delete sur un pointeur nul, c'est-à-dire à ne rien faire du tout.

Ayez aussi à l'esprit que shared_ptr perd son sens originel et se comporte davantage comme un weak_ptr, c'est-à-dire
que vous devez systématiquement vous assurer qu'il ne soit pas nul avant de l'utiliser.

Vu la lourdeur de cette écriture et le changement de sémantique introduit, on comprend mieux pourquoi il est déconseillé
d'employer des pointeurs intelligents sur des objets dérivant de QObjet.

lien : Faq C++ : pointeurs intelligents

- 39 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

lien : Tutoriel : Pointeurs intelligents

Comment faire un delete sur un QObject de manière sûre ?


Auteurs : Yan Verdavaine ,
Faire un delete sur un QObject peut être très dangereux. Par exemple, avec le système de signaux et de slots, il est
parfois difficile d'être sûr qu'il n'est pas utilisé par la pile d'appel au moment du delete : on veut détruire un bouton
quand on clique dessus.

Class widget : public QWidget


{
Q_OBJECT
QPointer<QPushButton> m_but ;
public :
widget ()
{
m_but = new QPushButton(this);
connect(m_but,SIGNAL(clicked()),this,SLOT(butClicked()));
}
public slots :
void butClicked()
{
delete m_but;
m_but = 0;
}
} ;

Lorsque l'on appuie sur le bouton, le signal clicked est émis. Ce qui va appeler directement le slot butClicked(). À ce
niveau, la pile d'appel correspond à :

widget => butClicked()


m_but => clicked()

Ainsi, le bouton sur lequel on veut faire un delete est utilisé par la pile d'appel. Le delete va produire une erreur mémoire
et votre application se retrouve en état indéterminé.

Pour cela, QObject fournit la fonction deleteLater, qui va poster un évènement et le QObject sera détruit par l'eventloop
dès que tous danger est écarté.

La fonction devient tout simplement :

void butClicked()
{
m_but->deleteLater();
}

Il est intéressant de constater que cette fonction est un slot et peut donc être connecté à un
signal.

- 40 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Il est aussi possible d'appeler plusieurs fois cette fonction sans aucun danger.

Un QObject en tant que membre d'une classe ?


Auteurs : Yan Verdavaine ,
Lorsque l'on utilise un QObject (ou un enfant) en membre d'une classe, on peut se demander s'il faut utiliser un pointeur
ou non. Voici ce que je vous conseille.

• Objet optionnel : Si l'objet est optionnel, il est fortement conseillé d'utiliser le pointeur intelligent
QWeakPointer (ou QPointer pour Qt avant 4.6) qui va permettre de savoir si le QObject pointé existe.
• Les objets partagé entre classes : Les QObject ne sont pas prévue pour être utilisée par plusieurs classes en
même temps. Donc cela ne devrait pas se poser.
• Les QWidget : Comme ils peuvent être reparentés (par les layouts par exemple), il est fortement conseillé
d'utiliser des pointeurs pour garantir leur destruction de manière correcte.
• Les autres : Au choix. Il peut être intéressant de ne pas utiliser de pointeur pour éviter de faire les allocation à
la main. Ceci ne pose aucun problème avec le système de destruction parent/enfant, car ils seront détruit avant
la classe. Toute fois il ne faut pas oublier de mettre this en parent.

class monObj : QObject


{
QTimer m_timer;
public :
monObj ()
: m_timer(this)
{
}
}

class monObj : QObject


{
QTimer m_timer;
public :
monObj ()
{
m_timer.setParent(this);
}
}

Il est très important que tous les QObject en membre d'une classe ait pour parent this. QWidget est un cas particulier
où le parent dépend de son niveau dans l'arbre parent/enfants des widgets et où le parent est forcément un QWidget.

- 41 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sommaire > QtCore > QString


Faut-il utiliser les pointeurs avec QString ?
Auteurs : Benjamin Poulain ,
Ce n'est pas nécessaire. QString utilise un pointeur partagé pour stocker les caractères. Les opérations de copie et
d'affectation sont aussi performante qu'en manipulant des pointeurs.

QString texte = "Developpez!";


// la copie est rapide
QString copie = texte;
QString secondeCopie;
// l'affectation est rapide
secondeCopie = copie;
// utiliser QString en argument est efficace
uneFonction(texte);

lien : Comment Qt optimise-t-il les copies ?

Comment transformer un QString en std::string et réciproquement ?


Auteurs : Matthieu Brucher ,
Pour transformer un std::string en QString, utilisez la fonction statique QString::fromStdString().

Pour l'opération inverse, transformer un QString en std::string, utilisez la fonction membre toStdString().

Comment convertir un QString en chaîne C (char *) ?


Auteurs : Benjamin Poulain ,
Pour convertir un object QString en chaîne de 8 bits, il faut utiliser les méthodes toAscii(), toLatin1(), toUtf8(),
toLocal8Bit(). Ces méthodes retournent un objet QByteArray, qui permet de gérer la mémoire. QByteArray fournit
les méthodes constData() et data() pour accéder à un pointeur sur un tableau de char. Ce pointeur est valide aussi
longtemps que l'objet n'est pas modifié ou détruit.

QString adresseIp("127.0.0.1");
QByteArray adresseIpEncodee = adresseIp.toUtf8();
printf(adresseIpEncodee.constData());

Avec des chaînes de type C, il faut être attentif à la mémoire. Par exemple, le code suivant provoquera des problèmes
de mémoire.

QStringList list;
list << "C" << "C++" << "Qt";
QList<const char*> ipListEnChar;
foreach(QString ip, list)
{
QByteArray adresseIpEncodee = ip.toUtf8();
ipListEnChar << adresseIpEncodee.constData(); // le pointeur sera invalide
}
foreach(const char *str, ipListEnChar)
{
printf(str); // le résultat est imprévisible

- 42 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Il faut revenir aux vielles habitudes de C et gérer les allocations à la main. Il suffit dans l'exemple de s'assurer que les
objets QByteArray ne soient pas détruits.

QStringList list;
list << "C" << "C++" << "Qt";
QList<QByteArray> ipListEnCharData;
QList<const char*> ipListEnChar;
foreach(QString ip, list)
{
QByteArray adresseIpEncodee = ip.toUtf8();
ipListEnChar << adresseIpEncodee.constData();
ipListEnCharData << adresseIpEncodee;
}
foreach(const char *str, ipListEnChar)
{
printf(str);
}

Dans un problème réel, le tableau de char * serait caché dans les fonctions C utilisées, et il faut être rester attentif à
la gestion de la mémoire.

Remarque : QString permet aussi une conversion vers les formats std::string et std::wstring fournis par la STL.

lien : Comment transformer un QString en std::string et réciproquement ?

Comment formater du texte avec QString ?


Auteurs : Yan Verdavaine ,
QString implémente un équivalent au printf() et boost::format pour faire du formatage de chaîne. Pour cela, QSting
utilise des formateur sous la forme %n (où n est un nombre) et les fonctions arg.

Chaque fonction arg retourne une nouvelle chaîne où les %n sont placés par ordre croissant. La fonction arg possède
énormément de versions différentes qui vont permettre de remplacer un formateur par un nombre ou une chaîne. De
plus, si plusieurs formateurs ont le même nombre, ils seront remplacés par la même valeur.

QString s = "%2 et %1 ou %1 et %3";


// On remplace le plus petit formateur contenu dans s
// tous les %1 sont remplacé par le nombre 42
// s1 == "%3 et 42 ou 42 et %2"
// s n'est pas modifié
QString s1 = s.arg(42);

// On remplace plusieurs formateurs contenus dans s1 dans l'ordre croissant


// %2 est remplacé par hello
// %3 est remplacé par salut
// s2 == "salut et 42 ou 42 et hello"
// s1 n'est pas modifié
QString s2 = s1.arg("hello","salut");

Cet outil est d'autant plus puissant que l'on peut faire du formatage récursif : l'on peut ajouter des formateurs lors
du remplacement d'un formateur.

QString s = "%1";
//%1 est remplacé par "formatage récursif : %1 %2"

- 43 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

// s1 == "formatage récursif : %1 %2"


// s1 est composé par deux nouveau formateurs.
QString s1 = s.arg("formatage recurssif : %1 %2");

Comment convertir un nombre en chaîne de caractère ?


Auteurs : Benjamin Poulain ,
QString fournit la méthode statique number() pour convertir des nombres0

QString cinquante = QString::number(50);


QString unTier = QString::number(0.33333);

Avec QString::number(), il est aussi possible de spécifier la base pour les entiers, et le format et la précisions pour les
réels. La méthode statique QString::number() possède un équivalent pour convertir un nombre dans un objet existant :
QString::setNum().

QString cinquante("Ce texte sera supprimé");


cinquante.setNum(50); // cinquante vaut "50"

Pour insérer un nombre dans une chaîne de caractère, il est plus simple d'utiliser les fonctionnalités de formatage de
QString.

lien : Comment formater du texte avec QString ?


lien : Comment formater les nombres entiers ?

Comment formater les nombres entiers ?


Auteurs : François Jaffré ,
Qt à l'aide de la classe QString peut formater des chaînes de caractères. Cela est possible grâce à la méthode sprintf()
qui permet de formater les chaînes, comme en C, ou à la méthode arg() qui est plus propre à Qt.

Exemple : on souhaite formater une chaine de la forme Image_00032.

Avec sprintf()
QString str;
int val=32;
str = str.sprintf("Image_%05d" , val ); // str == "Image_00032"

Avec arg()
QString str = "Image_%1";
int val=32;
str = str.arg(val, 5 , 10 , QChar('0') ); // str == "Image_00032"

Comment connvertir un QString en un nombre ?


Auteurs : François Jaffré ,
La classe QString implémente directement des méthodes pour transformer une chaîne de caractères en variable
numérique. De plus ces méthodes possèdent des paramètres optionnels :

- 44 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

• Comme la conversion peut être impossible, un pointeur vers un booléen permet de récupérer le résultat de la
conversion ;
• Pour la conversion vers un des types entiers, il est possible de spécifier la base (2 à 36).

Utilisation sans paramètre.

QString -> double


QString str="123.36969577";
double number = str.toDouble();//number == 123.36969577

Utilisation avec paramètre qui permet la vérification de la conversion.

QString -> int


QString str1="128";
QString str2="Qt128";
bool ok; // Permet de vérifier si la conversion a réussi ou non.
int num1 = str1.toInt(&ok); // ok == true et conversion réussie : num1 ==128
int num2 = str2.toInt(&ok); // ok == false et conversion échouée : num2 == 0

Conversion d'une chaîne dans une base particulière (hexadécimal, octal...).

Conversion d'une chaine dans une base hexa


QString str = "FFFF";
bool ok; // Toujours utile à la vérification de la conversion
int num = str .toInt(&ok,16); // ok == true et num == 65535
str == "0xFFFF"; // Les conventions standards du C, par exemple, ici, "0x" pour une chaîne
hexadécimale, sont reconnues.
num = str.toInt(&ok,16); // ok == true et num == 65535

Remarque : Le même principe de conversion existe pour les autres types de variables numériques.

• toLong()
• toShort()
• toUInt()
• toUShort()
• toULongLong()

Comment formater les nombres réels ?


Auteurs : Benjamin Poulain ,
La méthode statique QString::number () prend des arguments facultatifs qui permettent de formater les nombres réels.

Le premier argument est un caractère qui précise le format, les formats possibles sont :

• 'e' : format scientifique avec un e minuscule, comme 2.997925e+08 ;


• 'E' : format scientifique avec un e majuscule, comme 2.997925E+08 ;
• 'f' : format classique pour les réels, comme 299792458.0 ;
• 'g' : choisir automatiquement le plus concis entre 'e' et 'f', c'est le mode par défaut ;
• 'G' : choisir automatiquement le plus concis entre 'E' et 'f' ;

- 45 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

// vaut "2.997925e+08"
QString::number(299792458.0, 'e');
// vaut "299792458.000000", voir plus loin pour comprendre pourquoi
QString::number(299792458.0, 'f');

Le second argument permet de spécifier la précision utilisée. Par défaut, Qt utilise une précision de 6, ce qui explique
le résultat de l'exemple précédent.

// vaut "299792458.0"
QString::number(299792458.0, 'f', 1);

Il est suggéré de toujours préciser le format lorsque l'on veut convertir des réels (que ce soit avec Qt ou autre). Dans le
cas contraire, un affichage inattendu peut apparaître lorsque les nombres deviennent très petits ou très grand, ce qui
n'apparaît généralement pas dans les tests lors du développement.

Pour insérer un réel dans une chaîne de caractère, il est plus simple d'utiliser la fonctionnalité de formatage de QString

lien : Comment formater du texte avec QString ?


lien : Comment connvertir un QString en un nombre ?

Comment tester si une chaîne de caractère est vide ?


Auteurs : Benjamin Poulain ,
QString fournit la méthode isEmpty() pour savoir si une chaîne est vide.

if(texte.isEmpty()){
...
}

Il est possible de comparer QString avec un tableau de char, ce qui permet aussi de tester si une chaîne est vide.

// mauvaise idée
if(texte == ""){
...
}

Cela fonctionne, mais il y a une conversion implicite de "" en QLatin1String, ce qui est inutile pour une chaîne vide et
est légèrement moins performant que l'exemple précédent.

Comment QString gère l'encodage des chaînes de caractères ?


Auteurs : Benjamin Poulain ,
En interne, QString stocke les caractères en Unicode 4.0 sur 16 bits, ce qui permet des opérations rapides quelque soit
le type de caractère utilisé.

Pour convertir un chaînes sur 8 bits en QString, il est possible de l'encoder grâce aux méthodes statiques fromAscii(),
fromLatin1(), fromUtf8(), et fromLocal8Bit().

- 46 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

QString infini = QString::fromUtf8("&#8734;");

Par défaut, QString interprète une chaîne C avec l'encodage Latin 1 (ISO 8859-1). Il est possible de changer ce
comportement de façon globale grâce à la méthode statique QTextCodec::setCodecForCStrings().

Pour convertir un objet QString en tableau de char, il faut utiliser une des méthodes toAscii(), toLatin1(), toUtf8() ou
toLocal8Bit(). Si d'autres encodages sont nécessaires, il suffit d'utiliser QTextCodec, qui permet d'encoder à peu prêt
n'importe quoi.

- 47 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sommaire > QtCore > Thread


Comment fonctionne QThread ?
Auteurs : Yan Verdavaine ,
QThread est une interface simple permettant la création et manipulation d'un thread. Pour les version de Qt supérieure
à la 4.4, elle ne peut être instanciée, car la méthode run() est virtuelle pure. Il faut donc créer une classe héritant de
QThread et qui réimplémente la méthode run(). Pour les version de Qt inférieures ou égales à la 4.4, par défaut, QThread
exécute une boucle d'événements.

Voici les principales fonctionnalités à connaître :


• run() : méthode exécutée par le thread ;
• exec() : fonction bloquante qui va exécuter une event loop dans le thread ; cette fonction ne peut être appelée
que par le run() ;
• quit() : slot qui stoppe la boucle d'événements du thread ;
• start() : slot qui lance un thread qui exécute la méthode run() ; cette fonction peut prendre en paramètre la
priorité donnée au thread ;
• setPriority() : modifie la priorité d'exécution du thread ;
• wait() : fonction bloquante qui attend la fin de l'exécution ; il est possible de spécifier un timeout.

Cette classe émet le signal started() lorsqu'un thread est lancé et finished() lorsque le thread est terminé.

Il existe trois manières de l'utiliser :


• Sans boucle d'événements : seuls des objets n'héritant pas de QObject peuvent être utilisés. C'est à vous de
gérer la condition de sortie de la fonction run(). Un signal étant thread safe, il n'y a aucun problème à en utiliser
dans ce cas.
• Avec boucle d'événements : si le thread doit utiliser des objets héritant de QObject, la boucle d'événements doit
être exécutée. Pour cela, il suffit d'utiliser la fonction exec() dans la méthode run().
• Fonctionnement par défaut pour Qt après 4.4 : QThread exécute une boucle d'événements. Le but est alors de
transférer les QObject que l'on veut vers ce QThread pour qu'il utilise le thread interfacer pour leurs exécution.
Cela implique que ces QObject doivent être manipuler qu'au travers du système de signaux et de slots de Qt.
Sinon les fonctions doivent être thread safe. Attention à la destruction de ces QObject.

Avant d'utiliser une QThread, voici quelques règles à bien comprendre :


• QThread n'est pas un thread et n'appartient pas au thread. Ses slots ne s'exécutent pas dans le thread qu'elle
interface.
• Seule la fonction run() devrait être implémentée. Cette fonction run() est similaire au main() du programme
principal. Son exécution correspond au moment où le thread existe réellement.
• Les QObjects appartiennent au thread qui les créé. Il faut donc créer/supprimer les QObject utilisés par le
thread dans la méthode run().
• Un signal étant thread safe, le thread peut utiliser les signaux du QThread implémenté.

Remarque : Qthread fournit aussi un slot nommé terminate() qui termine brutalement le thread. Cette fonction est à
éviter le plus possible.

lien : Comment est définie l'appartenance aux threads des objets Qt ?

Pourquoi ne faut-il pas faire de traitement IHM dans un thread ?


Auteurs : Yan Verdavaine ,
La grande majorité des API graphiques des divers OS ne sont absolument pas thread-safe. Le traitement IHM
dans différents threads génère des accès concurrents et donc des crashs de l'application.

- 48 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

C'est pour cela que Qt oblige les traitements IHM dans le thread principal (celui exécutant le main() du programme).
Attention, cette vérification n'est effectuée uniquement par des assertions, en compilation débug.

Si vous devez manipuler l'affichage par un thread, utilisez le système de connexion signal/slot.

Comment est définie l'appartenance aux threads des objets Qt ?


Auteurs : Yan Verdavaine ,
Chaque QObject possède une affinité avec un QThread. Et ainsi chaque QObject va utiliser la boucle événementielle
exécutée par le thread interfacé par ce QThread.

Par défaut, cette affinité dépend du thread qui créé le QObject. Le QObject prendra le QThread qui interface ce thread.
Attention, lorsque l'on créé un QObject, le parent doit être associé au QThread interfaçant le thread.

#include <QtGui>

class monThread : public QThread


{
public :
monThread()
{
QObject obj2;
qDebug()<< "obj 2 :" << obj2.thread();
}
protected :
void run()
{
QObject obj3;
qDebug() << "obj 3 :" << obj3.thread();

QObject obj4(this);
}

};

int main(int argc, char *argv[])


{
QApplication app(argc, argv);
qDebug() <<"thread principal :" << app.thread();
QObject obj1;
qDebug() <<"obj 1 :" << obj1.thread();
monThread t;
t.start();
t.wait();
return 0;
}

obj1 et obj2 sont créés par le thread principal et sont associés au même QThread que QApplication. obj3 est créé dans
le thread interfacé par QThread et est associé au QThread. obj4 génère un avertissement et son parent est 0.

Il est possible de transférer l'appartenance d'un QObject entre QThread grâce à la méthode moveToThread(). Attention
à ces quelques règles !

• Seul le thread associé au QThread du QObject doit utiliser cette fonction ;


• Le QObject ne doit pas avoir de parent ;
• Tous les enfants du QObject sont aussi transférés. Il est donc important que les QObject membres d'une classe
dérivée de QObject ait pour parent this (sauf les QWidget).

- 49 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

• Une fois transféré, le QObject ne doit plus être utilisé par l'ancien thread.

lien : Un QObject en tant que membre d'une classe ?

Comment utiliser les threads avec Qt ?


Auteurs : Yan Verdavaine ,
Qt fournit plusieurs possibilités pour manipuler des threads.

• QtConcurrent : un ensemble d'algorithmes simplifiant énormément l'utilisation des threads. Il partage un pool
de threads qui s'adaptera à la machine d'exécution.
• QThread : c'est un classe qui interface un thread. Elle va créer, stopper, faire exécuter sa méthode run() et
autres opération sur un thread.
• QThreadPool : pour optimiser la création de threads, il est possible de manipuler un pool de thread avec
QThreadPool. Ce pool de threads exécutera des classes héritant de QRunnable et réimplementant la méthode
run().

Comment se passe une connection entre threads ?


Auteurs : Yan Verdavaine ,
Par défaut, la connexion entre thread est asynchrone, car le slot sera exécuté dans le thread qui possède l'objet receveur.
Pour cette raison, les paramètres du signal doivent être copiables. Ce qui implique quelques règles simples :

• Ne jamais utiliser un pointeur ou une "référence non const" dans les signatures des signaux/slots. Rien ne
permet de certifier que la mémoire sera encore valide lors de l'exécution du slot ;
• S'il y a une référence const, l'objet sera copié ;
• Il est préférable d'utiliser des classes Qt car elles implémentent une optimisation de la copies (cf COW).

Il est possible d'utiliser ses propres classes. Pour cela, il faut :

• Que cette classe ait un constructeur, un constructeur de copie et un destructeur public ;


• L'enregistrer dans les métatypes par la méthode qRegisterMetaType().

Exemple d'utilisation de qRegisterMetaType


class A
{
public :
A() {};
A( const A&a) {...}
~A() {...}

...
}

void desConnect()
{
qRegisterMetaType <A>("A");
// Connexion entre deux objets de deux threads
connect( unObjet, SIGNAL( unSignal(const A &), unObjetDansUneAutreThread, SLOT(monSlot(const A
&)));
connect( unObjet, SIGNAL( unSignal2(A ), unObjetDansUneAutreThread, SLOT(monSlot2(A )));
}

- 50 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Contrairement aux slots, les signaux sont thread safe et peuvent donc être appelés par n'importe quel thread.

lien : Comment optimiser la copie de ses classes ?

Comment manipuler un mutex ?


Auteurs : Yan Verdavaine ,
Pour protéger des données partagées entre threads, Qt fournit la classe QMutex. Cette classe fournit une base :

• lock : bloque le mutex ;


• tryLock : essaie de bloquer le mutex (possibilité de mettre un timeout) ;
• unlock : libère le mutex.

Afin de simplifier sa manipulation, Qt fournit la classe QMutexLocker basée sur le pattern RAII qui permet de
manipuler correctement le mutex et éviter certains problèmes (un thread qui essaye de bloquer deux fois un mutex, un
mutex non débloqué suite à une exception...). QMutexLocker va bloquer le mutex lors de sa création et le libérer lors
de sa destruction. Il permet aussi de libérer (unlock()) et de rebloquer (relock()) le mutex.

QMutexLocker vs à la main
QMutex lock;
QMutex lock2;

void f()
{
// locker bloque le mutex lock
QMutexLocker locker(lock);
// on bloque le mutex lock2
lock2.lock();

// fonction qui génère un exception


uneFonction();

// fonction non appelée suite à l'exception


lock2.unlock();

// locker est détruit et va libérer lock


// malheureusement lock2 est toujours bloqué
}

Lorsqu'une ressource est partagée entre plusieurs threads, ces threads ont le droit d'accéder parallèlement à la ressource
uniquement s'ils ne font que des accès en lecture. Ainsi, pour optimiser les accès, Qt fournit QReadWriteLock, qui
est un autre mutex, beaucoup plus adapté. Contrairement à QMutex, QReadWriteLock va différencier les lock() en
lecture et écriture :

Mutex bloqué en lecture :


• Si un thread essaye de bloquer le mutex en lecture : aucune attente, le thread peut accéder à la ressource ;
• Si un thread essaye de bloquer le mutex en écriture : le thread attend la libération du mutex.

Mutex bloqué en écriture :


• Dans les deux cas, le thread attend la libération du mutex.

Comme QMutex, cette classe fournit une base :

• lockForRead() : bloque le mutex en lecture ;


• tryLockForRead() : essaie de bloquer le mutex en lecture (possibilité de mettre un timeout) ;

- 51 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

• lockForWrite() : bloque le mutex en écriture ;


• tryLockForWrite() : essaie de bloquer le mutex en écriture (possibilité de mettre un timeout) ;
• unlock() : libère le mutex.

De la même manière que QMutexLocker, Qt fournit deux classes qui simplifient la manipulation de ce mutex.

• QReadLoker : manipulation du mutex en lecture ;


• QWriteLoker : manipulation du mutex en écriture.

Comment mettre en pause un QThread ?


Auteurs : Yan Verdavaine ,
Pour diverses raisons, il peut être intéressant de mettre en pause l'exécution d'un thread sur une durée déterminé. Pour
cela la classe QThread fournit plusieurs méthodes statiques :

• sleep : pause le thread pendant n secondes ;


• msleep : pause le thread pendant n millisecondes ;
• usleep : pause le thread pendant n micro secondes.

Comment utiliser le système de signaux et de slots avec des threads ?


Auteurs : Yan Verdavaine ,
Il n'y a pas vraiment de meilleure solution. Mais voici une version qui utilise QThread comme une sorte de passerelle
de signaux et de slots. Pour cela, on utilise la possibilité de connecter un signal à un signal.

La technique est très simple. L'instance de QThread

• Ne possède aucun slot, car elle ne doit pas accéder aux objects manipulés par le thread ;
• Définira, au besoin, des signaux dans sa définissions de base, appelés des signaux sortantd ;
• Définira, au besoin, à la place des slots, des signaux qui serviront de passerelle vers les slots des objets utilisés
par le thread, appelés des signaux entrant ; dans ce cas il faut utiliser la boucle d'événements.

#include <QtCore>
// Simple class qui émet toutes les secondes un entier incrémenté
// Comme un signal est thread safe, le thread appelera le signal de QThread
class threadEmetteur : public QThread
{
Q_OBJECT
protected:
void run()
{
int i=0;
forever
{
sleep(1);
qDebug()<<"Emission de " << i << " depuis le thread " << (int) currentThreadId();
emit unEntier(i++);
}
}
signals:
// Émet un entier
void unEntier(int);
};

- 52 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

// Le second thread doit recevoir des signaux :


// on crée donc une classe qui sera utilisé en interne au second thread
// et connectée aux signaux entrants
class interthreadReceveur : public QObject
{
Q_OBJECT

public slots:
// Slot qui affichera un entier reçu
void afficheEntier(int i)
{
qDebug() << "Recu " << i << " depuis le thread " << (int) QThread::currentThreadId();
}
};

// Le second thread doit recevoir des signaux et les renvoie vers un objet interne
class threadReceveur : public QThread
{
Q_OBJECT

protected:
void run()
{
// Création de l'objet interne
interthreadReceveur receveur;
// Connexion des signaux entrant vers les slots d'exécutions
connect(this,SIGNAL( afficheEntier(int)),&receveur,SLOT( afficheEntier(int)));
// Lancement de la boucle d'événements
exec();
}

signals:
// Signal entrant qui sera redirigé vers l'objet interne
void afficheEntier(int i);

};

#include "main.moc"
int main(int argc,char**argv)
{
QCoreApplication app(argc,argv);
threadEmetteur te;
threadReceveur tr;
// Connexion d'un signal sortant vers un signal sortant
QObject::connect(&te,SIGNAL( unEntier(int)),&tr,SIGNAL(afficheEntier(int)));

tr.start();
te.start();
return app.exec();
}

On pourrait être tenté d'utiliser la fonction moveToThread sur le QThread en début du run()
pour exécuter ses slots dans le thread. Seulement, cela poserait des problèmes : par exemple,
pour redémarrer le thread après une première exécution, si vous utilisez start() comme un slot.

Comment équilibrer le temps CPU ?


Auteurs : Yan Verdavaine ,
Avant toute chose, il faut bien comprendre que, dans la grande majorité des cas, les OS font
déjà très bien leur travail et que vous n'aurez absolument pas besoin de faire tout ceci puisque
le problème est différent selon chaque OS. Donc, à utiliser en connaissance de cause.

- 53 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Lorsqu'un thread fait énormément de traitements, il a tendance à récupérer le maximum de temps CPU. Les autres
threads se retrouvent ainsi fortement ralentis voire en attente constante de temps CPU. Il existe quelques solutions pour
résoudre ce problème :

• La façon la plus simple est de diminuer la priorité d'exécution du thread. Pour ceci, il vous suffit d'utiliser la
fonction QThread::setPriority() avec une priorité inférieure ou égale à QThread::LowPriority.
• La seconde méthode est de mettre en pause régulièrement le thread. Lorsque le thread est en pause, l'OS va
récupérer le CPU utilisé par le thread et exécuter un autre thread. Une fois le thread réveillé, il est mis en
attente. Le problème de cette méthode est qu'il est assez difficile de déterminer le temps de pause à appliquer. Si
le temps de pause est trop faible, le thread va garder l'utilisation du CPU et cela ne règlera pas le problème. Si
le temps est trop long, le thread peut être ralenti inutilement.
• Depuis la version 4.5, QThread fournit une méthode publique statique assez intéressante :
QThread::yieldCurrentThread(). Avec cette méthode, contrairement à la mise en pause, le thread redonne la
main du CPU à l'OS et se met en attente. L'OS choisissant quel thread sera exécuté. Ainsi le temps CPU sont
toujours libérées régulièrement et théoriquement partagés. De la même manière, il est très difficile d'évaluer la
fréquence à utiliser pour appeler cette méthode.

lien : Comment mettre en pause un QThread ?

- 54 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sommaire > QtCore > Fichiers et répertoires

- 55 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sommaire > QtCore > Fichiers et répertoires > Opérations de base


Comment effacer un fichier ?
Auteurs : François Jaffré ,
Pour cela il faut utiliser les méthodes suivantes de QFile :

- 56 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

• bool QFile::remove() : permet d'effacer le fichier référencé par l'objet QFile ;


• static bool QFile::remove (const QString & fileName) : permet d'effacer le fichier "fileName".

Première methode
// On référence l'objet file au fichier
QFile file("C:/existe.txt");
// Efface le fichier "existe.txt" et renvoie true ou false si l'operation bien réussi
bool valid = file.remove();

Deuxième méthode
// Efface le fichier "existe.txt" et renvoie true ou false si l'opération a bien réussi
bool valid = QFile::remove("C:/existe.txt");

Comment vérifier si un fichier existe ?


Auteurs : François Jaffré ,
Pour cela il faut utiliser les méthodes suivantes de QFile :

- 57 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

• bool QFile::exists() const : permet de verifier si le fichier pointé par l'objet QFile existe.
• static bool QFile::exists (const QString & fileName) : permet de vérifier si le fichier "fileName" existe.

Première méthode
// On réference l'objet file au fichier
QFile file("C:/existe.txt");
// Si valid == true, le fichier existe
bool valid = file.exists();

Deuxième méthode
//Si valid == true, le fichier existe
bool valid = QFile::exists("C:/existe.txt");

Comment copier un fichier ?


Auteurs : François Jaffré ,
Pour cela QFile met à notre disposition les méthodes suivantes :

- 58 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

• bool QFile::copy (const QString & newName) : permet la copie du fichier contenu dans l'objet QFile.
• static bool QFile::copy (const QString & fileName, const QString & newName) : permet la copie du fichier
"fileName" en "newName".

Remarque : Ces deux méthodes renvoient true si la copie s'est bien passée et renvoie false dans le cas contraire. Si le
fichier spécifié "newName" existe déjà, la copie sera annulée et la méthode renverra false.

Utilisation de la première méthode


// On référence l'objet file au fichier
QFile file("C:/copie.txt");
// On copie le fichier copie.txt vers copieNext.txt
bool valid = file.copy("C:/copieNext.txt");

Utilisation de la deuxième méthode


// On copie le fichier copie.txt vers copieNext.txt
bool valid = QFile::copy ("C:/copie.txt", "C:/copieNext.txt");

Comment récupérer le chemin des répertoires spéciaux ?


Auteurs : François Jaffré ,
Qt, à partir de sa version 4.4, permet, avec la classe QDesktopServices, de récupérer les différents chemins des
répertoires spéciaux tels que Movies, Pictures, Temp, etc. C'est la méthode statique storageLocation(), qui prend en
argument une énumération de type StandardLocation, qui permet d'effectuer cela.
Exemple : on souhaite récupérer le répertoire Pictures de l'utilisateur.

QString PicturesPath = QDesktopServices::storageLocation(QDesktopServices::PicturesLocation);

La liste de tous les répertoires pouvant être récupérés correspond à l'énumération StandardLocation.

Remarque : si vous utilisez l'option QDesktopServices:: DataLocation, il est impératif que vous ayez défini
préalablement le nom de l'application et le nom de l'organisation à l'aide des méthodes setApplicationName() et
setOrganizationDomain() de la classe QCoreApplication.

Comment sélectionner un nom de fichier ou répertoire à partir d'une boite de dialogue ?


Auteurs : François Jaffré ,
Qt permet à l'aide de la classe QFileDialog une utilisation très simple de ces différentes boites de dialogue à l'aide de
méthodes statiques :

- 59 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

• QString getOpenFileName() : permet la récupération du chemin d'un fichier existant selectionné par
l'utilisateur ;
• QStringList getOpenFileNames() : permet la récupération du chemin de plusieurs fichiers existants selectionnés
par l'utilisateur ;
• QString getSaveFileName () : permet la récupération du chemin d'un fichier non existant dans le but d'être
sauvegardé ;
• QString getExistingDirectory() : permet la récupération d'un répertoire sélectionné par l'utilisateur.

Remarque : toutes ces méthodes fonctionnent sur le même principe.

Exemple

/* On souhaite sélectionner un fichier de type MP3 à l'aide d'une boite de dialogue avec les
contraintes suivantes:
*- Elle doit avoir comme label "Open mp3 file"
*- Elle doit s'ouvrir à partir du répertoire C:
*- Elle doit pouvoir filtrer les fichiers ayant l'extension .mp3 et aussi permettre de voir les
fichiers
ayant n'importe quelle extension*/

// Ouverture de la boîte de dialogue, modale


QString myOpenFile = QFileDialog::getOpenFileName(this, tr("Open mp3 file"),tr("C:\\"), tr("MP3
files (*.mp3);;All Files (*.*)"));
// On vérifie que l'utilisateur a bien sélectionné un fichier
// Si la chaine est vide, c'est que l'utilisateur a cliqué sur annuler
if(myOpenFile.isEmpty())
{
return;
}
// Un fichier à été sélectionné par l'utilisateur
else
{
...
}

Comment lister les fichiers d'un répertoire et de ses sous-répertoires ?


Auteurs : François Jaffré ,
Qt fournit, depuis sa version 4.3, la classe QDirIterator, qui permet la navigation entre répertoires. Cette classe possède
plusieurs surcharges du constructeur permettant de préciser le type de navigation que l'on souhaite entre les répertoires.
La navigation dans les répertoires se fait surtout à l'aide de deux méthodes :

- 60 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

• bool QDirIterator::hasNext () : retourne true tant qu'on n'est pas à la fin de l'arborescence ;
• QString QDirIterator::next () : fait avancer l'itérateur à la prochaine entrée et renvoie le chemin absolu de
celle-ci.

Récupération des fichiers MP3 et AVI d'un répertoire et de ses sous-répertoires


// On sélectionne le répertoire à partir duquel on va rechercher les fichiers AVI et MP3
QString selectDir = QFileDialog::getExistingDirectory
(
this,
tr("Ouvrir un répertoire"),
"",
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks
);

// On remplit une QStringList avec chacun des filtres désirés ici "*.mp3" et "*.avi".
QStringList listFilter;
listFilter << "*.avi";
listFilter << "*.mp3";

// On déclare un QDirIterator dans lequel on indique que l'on souhaite parcourir un répertoire et
ses sous-répertoires.
// De plus, on spécifie le filtre qui nous permettra de récupérer uniquement les fichiers du type
souhaité.
QDirIterator dirIterator(selectDir, listFilter ,QDir::Files | QDir::NoSymLinks,
QDirIterator::Subdirectories);

// Variable qui contiendra tous les fichiers correspondant à notre recherche


QStringList fileList;
// Tant qu'on n'est pas arrivé à la fin de l'arborescence...
while(dirIterator.hasNext())
{
// ...on va au prochain fichier correspondant à notre filtre
fileList << dirIterator.next();
}

Note 1 : Si on préfère récupérer une liste de type QFileInfoList au lieu d'une QStringList, il suffit d'utiliser la méthode
QDirIterator::fileInfo ().

Note 2 : Si on souhaite lister uniquement les fichiers d'un répertoire et non ceux de ses sous-répertoires, il est préférable
d'utiliser la méthode entryInfoList() de la classe QDir.

Comment connaître le chemin du répertoire courant ?


Auteurs : François Jaffré ,
Qt fournit la classe QDir pour manipuler les répertoires. Cette classe permet, entre autres, de récupérer le chemin du
répertoire courant de l'éxecution et de le modifier :

• QString QDir::currentPath() : chemin complet du répertoire


• QDir QDir::current () : QDir renvoie un objet de type QDir pointant sur le répertoire courant.
• bool QDir::setCurrent ( const QString & path ) : modifie le répertoire courant. Retourne true si la modification
a réussi.

Récupération du répertoire courant


QString CurrentDir = QDir::currentPath();

- 61 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Spécifier le répertoire courant.


QString CurrentDir = "C:/Users/Developpez/Downloads";
QDir::setCurrent(CurrentDir);

Remarque : Il est intéressant de préciser que le répertoire courant n'est pas forcement le même que le répertoire où
se trouve l'exécutable.

Comment récupérer le chemin du répertoire de l'exécutable ?


Auteurs : François Jaffré ,
Qt fournit, avec la classe QCoreApplication, des méthodes statiques permettant de récupérer facilement des
informations comme le chemin du répertoire de l'exécutable.

On exécute une application depuis C:\Users\developpez\Documents\test.exe.

// Contient le chemin complet du répertoire de l'exécutable (C:\Users\developpez\Documents)


QString MyAppDirPath = QCoreApplication::applicationDirPath();

//Contient le chemin complet de l'exécutable (C:\Users\developpez\Documents\test.exe)


QString MyAppPath = QCoreApplication::applicationFilePath ();

Comment récupérer le contenu d'un QIODevice dans un QString ?


Auteurs : Thibaut Cuvelier ,
QIODevice est une couche d'abstraction pour tous les périphériques, pour faire simple : cela permet que tous aient au
moins des fonctionnalités minimales, des fonctions aux noms identiques...

Diverses classes héritent de QIODevice : la plus connue, QFile, mais aussi QProcess, QAbstractSocket (et donc,
QTcpSocket et QUdpSocket), QBuffer...

QIODevice fournit la méthode readAll() pour récupérer le contenu dans un QByteArray.

QByteArray QIODevice::readAll();

Depuis le QByteArray, il est possible d'obtenir une QString, grâce aux constructeurs fournis. Vous pouvez aussi passer
par la méthode data() de QByteArray, qui vous permet de récupérer un char *.

Cependant, le résultat d'une telle opération peut être assez aléatoire : en effet, un QByteArray
peut contenir du texte avec n'importe quel encodage. Pour cela, il vaut mieux passer par un
QTextStream, qui permet de gérer l'encodage.

On ne peut jamais être sûr de la provenance d'un QByteArray, ni, donc, de la signification
des caractères qu'il comporte. Par exemple, un \0 revêt une signification particulière pour
QString : aux yeux de QByteArray, il s'agit d'un caractère comme les autres.

QString::QString ( QByteArray );

QTextStream::QTextStream (QByteArray );

- 62 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

QTextStream::setCodec ( QTextCodec );

Comment lister tous les lecteurs disponibles sous Windows ?


Auteurs : François Jaffré ,
Qt fournit la méthode statique QFileInfoList QDir::drives () qui permet de lister tous les lecteurs (C:\, D:\...) disponible
sur une machine Windows.

//On récupère tous les lecteurs disponibles dans une liste de type QFileInfoList
QFileInfoList ListDrives = QDir::drives();

foreach(const QFileInfo& FileInfo,ListDrives)


{
//Affichage de tous les lecteurs trouvés sur la machine
qDebug() << FileInfo. filePath();
}

Cette methodes est aussi disponible sous Mac OS X et Linux. Cependant, elle retournera
uniquement la racine du système, c'est-à-dire /.

- 63 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sommaire > QtCore > Fichiers et répertoires > Lecture et écriture


Comment écrire dans un fichier texte ?
Auteurs : François Jaffré ,
L'écriture dans un fichier texte se fait comme pour la lecture à l'aide de la classe QTextStream. Celle-ci fournit
l'opérateur << qui possède énormément de surcharges pour l'écriture dans un fichier. De plus, on peut spécifier le jeu
de caractères utilisé pour l'écriture avec la méthode QTextStream::setCodec.

Un exemple : on souhaite écrire le fichier suivant avec le jeu de caractères UTF-8.

Bonjour,
Nous sommes le 3 avril 2009

// Création d'un objet QFile


QFile file("Qt.txt");
// On ouvre notre fichier en lecture seule et on vérifie l'ouverture
if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
return;

// Création d'un objet QTextStream à partir de notre objet QFile


QTextStream flux(&file);
// On choisit le codec correspondant au jeu de caractère que l'on souhaite ; ici, UTF-8
flux.setCodec("UTF-8");
// Écriture des différentes lignes dans le fichier
flux << "Bonjour," << endl << "Nous sommes le " << 3 << " avril " << 2009 << endl;

Comment lire d'un fichier texte ?


Auteurs : haraelendil ,
La classe QTextStream offre des fonctionnalités intéressantes.

QString fileName = "fichier.txt";


QFile fichier(fileName);
fichier.open(QIODevice::ReadOnly | QIODevice::Text);
QTextStream flux(&fichier);

On peut ensuite lire le fichier de plusieurs façons.

* Intégralement.

QString tout = flux.readAll();

* Ligne par ligne.

QString ligne;
while(! flux.atEnd())
{
ligne = flux.readLine();
//traitement de la ligne
}

- 64 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

* Mot par mot.

QString mot;
while(! stream.atEnd())
{
stream >> mot;
// traitement du mot
}

La classe QTextStream offre une moyen simple d'écrire ou de lire du texte, d'en extraire ou d'ajouter des lignes, des
mots ou des nombres, un QTextStream pouvant fonctionner avec un QIODevice, une QString ou même un QByteArray.
Les opérateurs surchargé << et >> permettent d'opérer sur un QTextStream de façon très simple.
Remarque : Cette classe prend en compte l'encodage du texte.

Mais on peut aussi lire intégralement le contenu d'un fichier sans passer par la classe QTextStream, mais cela nécessite
de passer par la classe QByteArray.

QString fileName = "fichier.txt";


QFile fichier(fileName);
fichier.open(QIODevice::ReadOnly);
QByteArray data;

data = fichier.readAll();
QString ligne(data);

De même, on peut lire le fichier ligne par ligne.

QString fileName = "fichier.txt";


QFile fichier(fileName);
fichier.open(QIODevice::ReadOnly);
QByteArray data;

while(!fichier.atEnd())
{
data = fichier.readLine();
QString ligne(data);
//traitement de la ligne
}

Comment écrire et lire dans un fichier binaire ?


Auteurs : François Jaffré ,
Qt permet facilement d'écrire ou de lire dans un fichier de type binaire. Ceci se fait à l'aide de la classe QFile pour
l'ouverture et la fermeture du fichier et de la classe QDataStream pour l'écriture ou la lecture de celui-ci. L'intérêt
d'utiliser la classe QDataStream est d'être indépendant de la machine au niveau de l'encodage des octets. Dans les faits
cela veut dire qu'un fichier binaire étant écrit à l'aide de la classe QDataStream sous Windows par exemple peut être
lu sans problème sous toutes les autres plateformes supportant Qt (Mac, Linux...).

Remarque : par défaut, QDataStream travaille en big-endian.

Écriture d'un fichier binaire


// Utilisation d'un vecteur sur qint32 et pas sur int pour préserver la portabilité
QVector<qint32> vec;

- 65 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Écriture d'un fichier binaire


// On remplit le vecteur
vec.push_back(1);
vec.push_back(2);
vec.push_back(3);
vec.push_back(4);

// Utilisation d'un qint32 pour préserver la portabilité


qint32 value = 67;

// Initialisation de la QString qui sera enregistrée dans le fichier binaire


QString str = "Cette chaine sera sauvegardée dans un fichier binaire";

QFile file("MyFile.bin");
// Ouverture du fichier en lecture seule
if (!file.open(QIODevice::WriteOnly))
return;
// Création de notre QDataStream à partir de notre fichier précédemment ouvert
QDataStream binStream(&file);
// On spécifie la version de l'encodage qui va être utilisé par notre objet QDataStream
binStream.setVersion(QDataStream::Qt_4_4);
// On écrit nos differents objet dans le fichier
binStream << str << value << vec;
// On ferme le fichier
file.close();

Lecture d'un fichier binaire


// Utilisation des mêmes types utilisés lors de l'écriture
QVector<qint32> vec;
qint32 value;
QString str;

QFile file("MyFile.bin");
// Ouverture du fichier en lecture seule
if (!file.open(QIODevice::ReadOnly))
return;
// Création de notre QDataStream à partir de notre fichier précédemment ouvert
QDataStream binStream(&file);
// On spécifie exactement le même type d'encodage que celui utilisé lors de l'écriture
binStream.setVersion(QDataStream::Qt_4_4);
// Lecture des différents objets contenus dans notre fichier binaire
binStream >> str >> value >> vec;
// Fermeture du fichier
file.close();

- 66 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sommaire > QtCore > Fichiers et répertoires > Récupérer des informations
Comment obtenir des informations de fichiers ?
Auteurs : Thibaut Cuvelier ,
La classe QFileInfo est réservée à cet usage. Elle est prévue pour pouvoir être utilisée sous toutes les plateformes de
la même manière.

Avant de pouvoir voir les informations d'un fichier, vous devez créer un objet QFileInfo. Pour ce faire, il y a trois
manières de procéder.

1. Vous utilisez le chemin vers le fichier (QString).

Tous ces paramètres sont équivalents :

• QString ("/home/qt/bin/qmake")
• QString ("/home/./qt/lib/../bin/qmake")
• QString ("./../../home/./qt/lib/../bin/qmake") (si vous vous situez au deuxième niveau d'arborescence dans un
point de montage)

QFileInfo qmake (QString ("/home/qt/bin/qmake") );

2. Vous réutilisez un QFile.

QFile qmakeFile (QString ("/home/qt/bin/qmake") );


QFileInfo qmake (qmakeFile);

3. Vous utilisez le chemin vers le fichier (QDir) et son nom (QString).

QDir qmakeDir ( QString ("/home/qt/bin/qmake") );


QFileInfo qmake (qmakeDir, QString ("qmake") );

Ensuite, vous pourrez utiliser les méthodes de QFileInfo pour récupérer les informations qui vous sont nécessaires.

lien : Comment récupérer le nom de fichier ?


lien : Comment distinguer les fichiers des dossiers ?
lien : Comment vérifier les droits sur un fichier ?
lien : Comment récupérer l'emplacement d'un fichier ?
lien : Comment savoir s'il s'agit d'un bundle ? (Mac OS X)

Comment obtenir les informations des fichiers d'un dossier ?


Auteurs : Benjamin Poulain ,
Pour obtenir des informations sur des fichiers, il faut utiliser la classe QFileInfo.

Pour récuperer les informations des fichiers contenu dans un dossier QDir fournit la méthode QDir::entryInfoList().
Cette méthode prend en paramètres des filtres permettant de sélectionner le type de fichier requis.

Grâce aux caching des QFileInfo dans QDir, il est plus efficace d'utiliser cette méthode que de créer manuellement un
QFileInfo sur chacun des fichiers.

- 67 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

QDir dir("/developpez/");
foreach(QFileInfo &fileInfo, dir.entryInfoList()) {
fileInfo->isBundle();
}

lien : Comment obtenir des informations de fichiers ?

Comment récupérer le nom de fichier ?


Auteurs : Thibaut Cuvelier ,
Vous pouvez récupérer tout ou partie du nom de fichier.

QFileInfo file("/tmp/archive.tar.gz");

file.fileName() // == QString ("archive.tar.gz")

file.baseName() // == QString("archive")

file.completeBaseName() // base == QString("archive.tar")

file.suffix() // == QString("gz")

file.completeSuffix() // QString("tar.gz")

Comment distinguer les fichiers des dossiers ?


Auteurs : Thibaut Cuvelier ,
Qt nous fournit deux fonctions aux noms explicites : isFile() et isDir().

isDir() retournera true si le QFileInfo pointe vers un dossier ou vers un lien symbolique sur un dossier.

isFile() retournera true si le QFileInfo pointe vers un fichier ou vers un lien symbolique sur un fichier.

isSymLink() retournera true si le QFileInfo pointe vers un lien symbolique ou vers un raccourci (sous Windows
uniquement).

Sous Windows, quand vous ouvrez un raccourci, c'est le fichier .lnk qui est ouvert, et non le
fichier vers lequel il pointe.

QFileInfo file("/tmp/archive.tar.gz");
file->isDir() // == false
file->isFile() // == true
file->isSymLink // == false

QFileInfo libc ("/bin/libstdc++.so");


// En général, ce fichier est un lien symbolique
// vers /bin/libstdc++.so.3
libc->isDir() // == false
libc->isFile() // == true
libc->isSymLink // == true

QFileInfo usr ("/usr");


// Sous les UNIX, un point de montage
// est un dossier comme un autre
usr->isDir() // == true
usr->isFile() // == false

- 68 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

usr->isSymLink // == false

Comment vérifier les droits sur un fichier ?


Auteurs : Thibaut Cuvelier ,
Les trois droits principaux sont la lecture, l'écriture et l'exécution, que ce soit sur Windows (NT) ou sur un des dérivés
d'UNIX. Les seules exceptions sont les OS basés sur DOS : MS-DOS, PC-DOS, Windows 1 jusqu'à Millenium (toutes
les versions basées sur MS-DOS). Ces OS ne tiennent pas compte des droits.

Il existe une fonction pour récupérer les droits par droit : isReadable(), isWritable(), isExecutable(), en rapport avec
l'utilisateur qui lance votre programme. Il existe aussi la fonction permissions() qui permet de récupérer tous ces droits
pour tous, pour un groupe, pour un utilisateur et pour le possesseur.

QFileInfo file ("/etc/hosts");

if ( file.isReadable() )
// Opération de lecture sur fichier
if ( file.isWritable() )
// Opération d'écriture sur le fichier
if ( file.isExecutable() )
// Opération d'exécution sur le fichier

if ( file.permissions() &QFile::ReadUser )
// Opération de lecture sur le fichier

Quand vous utilisez un système de fichier NTFS (par défaut sous Windows NT), les droits ne
sont pas vérifiés, car cela prend trop de temps. Si vous désirez que Qt les vérifie quand même,
insérez cette ligne dans votre code.

extern Q_CORE_EXPORT int qt_ntfs_permission_lookup;

Ensuite, pour demander la vérification, il faut incrémenter qt_ntfs_permission_lookup. Pour la désactiver, il suffit de
le décrémenter.

qt_ntfs_permission_lookup++; // Activation de la vérification


qt_ntfs_permission_lookup--; // Désactivation de la vérification

Comment récupérer l'emplacement d'un fichier ?


Auteurs : Thibaut Cuvelier ,
Vous pouvez récupérer l'emplacement absolu ou relatif de ce fichier. Si le chemin est relatif, vous pouvez le transformer
en un chemin absolu.

QFileInfo qmake ("/home/qt/bin/qmake");


QFileInfo qmake2 ("/home/./qt/lib/../bin/qmake");
QFileInfo qmake3 ("./../../home/./qt/lib/../bin/qmake");
QFileInfo qmake4 ("C:/Qt/4.5.2/bin/qmake.exe");

qmake.absoluteFilePath() // == QString("/home/qt/bin/qmake")
qmake2.absoluteFilePath() // == QString("/home/./qt/lib/../bin/qmake")
qmake3.absoluteFilePath() // == QString("/home/./qt/lib/../bin/qmake")
qmake4.absoluteFilePath() == QString("C:/Qt/4.5.2/bin/qmake.exe")

- 69 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

qmake.absoluteDir() // == QDir ("/home/qt/bin")


qmake2.absoluteDir() // == QDir ("/home/./qt/lib/../bin")
qmake3.absoluteDir() // == QDir ("./../../home/./qt/lib/../bin")
qmake4.absoluteDir() == QDir ("C:/Qt/4.5.2/bin")

qmake.absolutePath() // == QString("/home/qt/bin/")
qmake2.absolutePath() // == QString("/home/./qt/lib/../bin/")
qmake3.absolutePath() // == QString("./../../home/./qt/lib/../bin/")
qmake4.absolutePath() == QString("C:/Qt/4.5.2/bin")

qmake.canonicalPath() // == QString("/home/qt/bin/")
qmake2.canonicalPath() // == QString("/home/qt/bin/")
qmake3.canonicalPath() // == QString("/home/qt/bin/")
qmake4.canonicalPath() == QString("C:/Qt/4.5.2/bin")

qmake.canonicalFilePath() // == QString("/home/qt/bin/qmake")
qmake2.canonicalFilePath() // == QString("/home/qt/bin/qmake")
qmake3.canonicalFilePath() // == QString("/home/qt/bin/qmake")
qmake4.canonicalFilePath() == QString("C:/Qt/4.5.2/bin/qmake.exe")

qmake.makeAbsolute(); // == false : déjà absolu


qmake2.makeAbsolute(); // == true
qmake3.makeAbsolute(); // == true
qmake4.makeAbsolute(); // == false : déjà absolu

Comment savoir s'il s'agit d'un bundle ? (Mac OS X)


Auteurs : Thibaut Cuvelier ,
Mac OS X rassemble toutes les applications dans ce qui apparaît comme un seul fichier. C'est ce fichier qui est appelé
bundle.

La classe QFileInfo propose quelques fonctions spécialisées dans la gestion de ces bundles.

QFileInfo file ("/Applications/Safari.app");

file.isBundle() // == true

file.bundleName() // == QString("Safari")

Comment obtenir la date de dernière modification ?


Auteurs : Thibaut Cuvelier ,
La classe QFileInfo nous propose la méthode lastModified(), qui retourne la date de dernière modification sous forme
de QDateTime.

QFileInfo file("/tmp/archive.tar.gz");

QDateTime lastModified = file.lastModified();

qDebug() << "File \"" << file.fileName() << "\" was modified on " ;
qDebug() << lastModified.date().toString("mm/dd/yyyy") << " at ";

- 70 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

qDebug() << astModified.time().toString("h:m ap");

Comment récupérer la taille d'un fichier ?


Auteurs : Thibaut Cuvelier ,
Pour obtenir la taille d'un fichier, nul besoin d'utiliser l'artillerie lourde comme QFile : un objet QFileInfo peut
retourner cette information

QFileInfo file ("~/file.ext");

qint64 size;

size = file.size();

Mais vous pouvez aussi utiliser QFile en ce but.

QFile file ("~/file.ext");

qint64 size;

size = file.size();

Si vous essayez de rapatrier la taille d'un fichier vide sous UNIX (comme /proc), la fonction
retournera 0. Le contenu sera généré lors de l'appel à read().

- 71 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sommaire > QtCore > Signaux et slots


Les signaux et autres slots ?
Auteurs : Matthieu Brucher ,
Les signaux et slots sont l'implémentation par Nokia du pattern observer. Ce pattern permet de prévenir les classes
voulant observer un événement.

Pour utiliser ce système, il faut hériter de QObject, soit directement, soit à l'aide d'un des objets dérivés de QObject.
Ensuite, il faut définir la macro Q_OBJECT qui servira à qmake puis à moc pour générer le code nécessaire à
l'utilisation de ces fonctions.

Pour déclarer des signaux, il suffit d'indiquer :

signal:
void monSignal();

Pour que moc génère le code qui va bien et pour que le signal puisse être utilisé. On appellera un signal par :

emit monSignal();

Ces signaux peuvent être connectés à d'autres signaux ou à des slots. Ces slots sont des fonctions du développeur qui
seront appelées dès que possible.

public slots:
void monSlot();

Une fois les slots définis, il suffit de connecter les signaux et les slots entre eux. Comme il s'agit de connexion directe, il
n'est pas possible de connecter un signal sans paramètre à un slot avec un paramètre. Pour cela, il faut utiliser entre-
temps QSignalMapper.

connect(this, SIGNAL(monSignal(), somethingElse, SLOT(monSlot()));;

On constatera aussi que signaux et slots ne peuvent pas retourner de valeur, pour l'instant.

lien : Les signaux et slots


lien : Tutoriel sur les signaux et slots de Qt 4

Comment s'interfacent les signaux et les slots?


Auteurs : Nykoo ,
Dans la question Les signaux et autres slots ? nous avons vu comment s'interface une connexion entre signaux et slots
simples, c'est à dire sans transmission de valeur. Or, les signaux et slots ont la capacité de se transmettre des données
par le biais de leurs arguments.

Prenons l'exemple de la classe QLineEdit de Qt.

- 72 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Son signal textChanged( const QString& ) permet de récupérer le texte présent dans le QLineEdit au moment de
l'émission du signal. De même, son slot setText(const QString& ) permet de redéfinir le texte contenu dans le QLineEdit
à l'aide d'un objet QString.

Rappel : Il est possible de connecter un signal avec un slot, mais on peut également connecter un signal à un autre
signal. Pour créer une connexion signal/slot (ou signal/signal) qui permette la transmission de valeurs, il suffit d'écrire
la signature complète de chaque signal/slot dans la fonction connect().
Autrement dit, il faut indiquer le nom des signaux/slots en question, ainsi que les types des arguments qu'ils prennent
en paramètre.

Exemple de signature complète


monSignal(QString,int) //signature d'un signal
monSlot(QString,int) //signature d'un slot
connect(objet1,SIGNAL(monSignal(QString,int)),objet2,SLOT(monSlot(QString,int)))

Attention, car il faut prendre certaines précautions. Dans une fonction connect(), les types des arguments des deux
fonctions doivent être compatibles et placés dans le même ordre. Des arguments sont compatibles si le même objet est
en jeux. Par exemple, const QString & est compatible avec QString. Par contre, QString* et QString& ne le sont pas.
Voici un exemple de connexion avec 2 types compatibles.

connect(this,SIGNAL(monSignal(QString,int)),somethingElse,SLOT(monSlot(const QString&#38;,int)));

Cependant, le signal ou le slot qui est situé dans la partie droite de la fonction connect() peut avoir un nombre
d'arguments inférieur ou égal à celui du signal situé à gauche. Par exemple la connexion suivante est valide. L'argument
int sera simplement ignoré.

connect(this,SIGNAL(monSignal(QString,int)),somethingElse,SLOT(monSlot(QString)))

Comment créer ses propres signaux et slots avec transmission de valeurs?


Auteurs : Nykoo ,
Cette question nécessite d'avoir compris la création de signaux/slots simples (sans arguments) décrite dans la question
Les signaux et autres slots ?

Pour créer un signal ou un slot avec des arguments il suffit d'ajouter les noms des types dans le prototype.

class myClass : public xxx


{
Q_OBJECT
...
signals:
void monSignal(type1,type2)
public slots:
void monSlot(type1,type2);
...
}

Ainsi, pour émettre son signal il suffit d'utiliser le mot clef emit.

- 73 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Emmission d'un signal)


void fonction()
{
nom_type t;
emit monSignal(t);
}

La connexion se fera avec un signal ou un slot qui prend un argument de type nom_type.

Comment utiliser les auto-connexions ?


Auteurs : mac&cheese ,
Sous Qt, les connexions entre les signaux et slots peuvent être mises en place, soit manuellement, soit automatiquement,
en utilisant la capacité qu'a QMetaObject d'établir des liens entre ces derniers.

Cette partie ne concerne pas les Les signaux et autres slots ? : elle traite de la méthode automatique.

Bien qu'il soit plutôt aisé d'implémenter un slot et de le connecter dans le constructeur, nous pouvons tout aussi bien
utiliser l'outil d'auto-connexion de QMetaObject pour connecter le signal clicked() de myButton à un slot dans notre
classe, ou pour connecter les signaux et les slots clicked() :

QMetaObject::connectSlotsByName(QObject *object);

Cette fonction du QMetaObject de Qt connecte automatiquement tous slots qui respectent la convention
on_Nomobjet_Nomsignal() au signal Nomsignal() correspondant de l'object Nomobjet. Deux conditions sont à remplir.

• L'objet NomObjet doit être un enfant de l'objet passé en paramètre à la méthode connectSlotByName().
• Les objets (parents et enfants) doivent être nommés avec la fonction setObjectName(const QString& name).

Exemple
class MainWindows : public QWidget
{
Q_OBJECT
public :
MainWindows(QWidget * parent = 0);

public slots :
// slot qui sera connecté au signal clicked() de l'objet myButton
// par l'autoconnect
void on_myButton_clicked();

};

MainWindows::MainWindows(QWidget * parent):QWidget(parent)
{
...
QPushButton * pButton = new QPushButton("essai auto connect");
// nom du bouton pour être retrouvé par l'autoconnect
pButton->setObjectName("myButton");
...
// auto connection des signaux/slots
QMetaObject::connectSlotsByName(this);
}

- 74 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Qupposons, cette fois-ci, que nous créons notre fenêtre via le Qt Designer et non plus en ligne de code. Nous possédons
alors un fichier supplémentaire, à savoir : mainwindows.ui. Lors de la compilation, l'outil uic de Qt, se charge de générer
le code de la fonction setupUi() de notre fenêtre mainwindows.ui. Le code généré utilise alors de la même façon :

• setObjectName(const QString & name) : pour nommer les objets définis dans mainwindows.ui ;
• QMetaObject::connectSlotsByName : pour autoconnecter les objets définis dans mainwindows.ui pendant
l'appel à setupUi().

Il est donc possible d'utiliser, de la même façon, les auto-connexions sur une GUI codée à la main que sur une GUI
créée à l'aide de Qt Designer.

Si deux enfants ont le même nom, l'auto-connect ne se fera que sur le premier enfant trouvé.

Si QMetaObject::connectSlotsByName est appelé plusieurs fois, les connections générées


seront multiples. Lors de l'utilisation d'un *.ui, ne pas oublier que la fonction setupUi()
appelle l'autoconnexion.

Utilisation de autoconnect sans *.ui Utilisation de autoconnect avec *.ui

Comment paramétrer un slot selon les objets qui lui sont connectés ?
Auteurs : Kinj1 ,
Qt propose de nombreuses classes avec de nombreux signaux déjà définis. Cependant, il peut parfois être intéressant
d'ajouter de l'information à ces signaux afin de les paramétrer selon l'objet émetteur. On pourrait ainsi vouloir que
différents boutons réalisant une action commune, par exemple ouvrir une page web lorsque l'on clique dessus, soient
connectés à un même slot auquel on précise l'URL à utiliser. Seulement, le signal clicked() de la classe QPushButton ne
transmet aucun paramètre, ce qui ne permet pas de spécifier l'URL.

Une première solution consiste alors à connecter le signal clicked() de chaque bouton à un slot différent qui se contentera
d'appeler la fonction d'ouverture de la page web avec l'url correspondante. Cependant, comme il est nécessaire de créer
un slot différent par bouton, cela rallonge inutilement la taille du code, surtout lorsqu'il y a un grand nombre de boutons.

Une autre solution est d'utiliser la classe QSignalMapper. Dans notre exemple, celle-ci va s'occuper d'appeler le slot
ouvrant la page web avec un paramètre configuré pour chacun des boutons (l'URL de la page). Nous avons donc
d'un côté les signaux clicked() des différents QPushButton, et de l'autre un slot openUrl(const QString& url) et le
QSignalMapper au milieu pour faire les correspondances.

Tout d'abord il faut créer un objet QSignalMapper, puis connecter les signaux des boutons à son slot map(). On définit
alors, pour chacun des boutons, le paramètre à utiliser pour l'appel à openUrl() via setMapping().

mapper = new QSignalMapper();

// Bouton 1
connect(bouton1, SIGNAL(clicked()), mapper, SLOT(map()));
mapper->setMapping(bouton1, "http://url1");

// Bouton 2
connect(bouton2, SIGNAL(clicked()), mapper, SLOT(map()));
mapper->setMapping(bouton2, "http://url2");

// Autres boutons ?

- 75 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Enfin, il suffit de connecter le signal mapped() de QSignalMapper à notre slot final. Ainsi quand un bouton émettra son
signal, le slot openUrl() sera utilisé avec le paramètre correspondant au bouton.

connect(mapper, SIGNAL(mapped(const QString &)), this, SLOT(openUrl(const QString &)));

Note : QSignalMapper ne se limite pas à des paramètres de type QString. Il est également possible d'utiliser des entiers
ou encore des QWidget* et des QObject*. Il faut dans ce cas utiliser le signal mapped() correspondant au type que l'on
veut transmettre.

Quelles sont les différentes méthodes d'exécution d'un slot ?


Auteurs : Denys Bulant ,
Un slot n'est, au final, rien de plus qu'une fonction normale à laquelle est rattachée quelques informations liées au
concept de méta-objet de Qt. En tant que tel, il est tout à fait possible de les appeler comme une fonction, et ce, de
façon inter-thread (avec les précautions qui s'impose dans un tel contexte). Comme précisé dans Comment fonctionne
QThread ?, l'utilisation correcte et sûre de slots dans un thread requiert l'exécution d'une boucle d'événements
(eventloop).

On peut répertorier les méthodes d'appel dans 2 catégories :

• Appel direct (à la façon d'une fonction normale) ;


• Appel par un signal (paradigme classique et récurrent lors de l'écriture d'une application utilisant Qt).

Cette dernière catégorie peut être elle-même divisée en deux autres catégories.

• Appel direct ;
• Appel placé en queue de la boucle d'événement du thread récepteur.

Dans le premier cas, le slot est exécuté dans le contexte du thread appelant.

Dans le second cas, le contexte d'exécution du thread dépend du mode de connexion fourni à QObject::connect.

• Directe (Qt::DirectConnection) : le slot est appelé immédiatement après l'émission du signal, et il est exécuté
dans le thread contenant l'émission du signal ;
• Placé en queue (Qt::QueuedConnection) : le signal est traité comme un événement et le slot concerné est donc
appelé lors du prochain passage dans la boucle d'événement du thread dans lequel le destinataire vit (c'est-
à-dire le thread dans lequel il a été créé ou si QObject::moveToThread() a été utilisé, dans le thread qui a été
donné à cette fonction) ;
• Automatique (Qt::AutoConnection, paramètre par défaut): si le destinataire du signal vit dans le même thread,
la connexion correspond à une connexion directe ; dans le cas contraire le comportement est celui d'une
connexion en queue.

#include <QtDebug>

class RandomObject : public QObject


{
Q_OBJECT

public slots:
void mySlot(int n)
{

- 76 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

qDebug() << "RandomObject::mySlot(int) appel depuis le thread #" <<


QThread::currentThreadId() << ": n=" << n << "\n";
}
};

class MyThread : public QThread


{
Q_OBJECT

public slots:
void threadSlot(int n)
{
qDebug() << "MyThread::threadSlot(int) appel depuis le thread #" <<
QThread::currentThreadId() << ": n=" << n << "\n";
}

protected:
virtual void run()
{
threadSlot(4);
exec();
}
};

class Window : public QWidget


{
Q_OBJECT

public:
Window()
{
QPushButton *threadSlotCall = new QPushButton("Appel de MyThread::threadSlot() tel une
fonction");
QPushButton *threadSlotCallSig = new QPushButton("Appel de MyThread::threadSlot() par un
signal");
QPushButton *queudSlotCallSig = new QPushButton("Appel de RandomObject::mySlot() par un
signal en queue");
moveRandomObjToThread = new QPushButton("Déplacer RandomObject vers le thread");
QPushButton *quitBtn = new QPushButton("Quitter");

QVBoxLayout *layout = new QVBoxLayout();


layout->addWidget(threadSlotCall);
layout->addWidget(threadSlotCallSig);
layout->addWidget(queudSlotCallSig);
layout->addWidget(moveRandomObjToThread);
layout->addWidget(quitBtn);

setLayout(layout);

/* La connexion vers 'obj' est faite par la boucle d'événement.


* Tant que obj vit dans le même thread que l'instance de Window l'appelant, l'appel du slot
est
* immédiat. Dans le cas contraire, l'appel se fait lors du prochain passage de la boucle
* d'événement du thread récepteur.
* Ici, tant que le bouton "Déplacer RandomObject vers le thread" n'est pas cliqué, l'appel
sera
* réalisé dès le prochain passage de la boucle d'événement du thread principal, ou thread
GUI.
* Une fois cliqué, l'objet ne vit plus dans le même thread et le slot est donc appelé lors
du
* prochain passage dans la boucle d'événement de l'objet 'thread'.
*/
connect(this, SIGNAL(mySignalForQueued(int)), &obj, SLOT(mySlot(int)),
Qt::QueuedConnection);

/* Le mode de connexion n'étant pas spécifié, la connexion est choisie de façon automatique.
* Puisque l'objet 'thread' vit dans le même thread que notre instance de Window, la
connexion

- 77 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

* est directe ; MyThread::threadSlot() est donc appelé immédiatement lors de l'émission de


* mySignal().
*/
connect(this, SIGNAL(mySignal(int)), &thread, SLOT(threadSlot(int)));

connect(threadSlotCall, SIGNAL(clicked()), this, SLOT(onCallThreadSlot()));


connect(threadSlotCallSig, SIGNAL(clicked()), this, SLOT(onCallThreadSlotSig()));
connect(queudSlotCallSig, SIGNAL(clicked()), this, SLOT(onCallThreadQueuedSlotSig()));
connect(moveRandomObjToThread, SIGNAL(clicked()), this, SLOT(moveRandomObjectToThread()));

connect(quitBtn, SIGNAL(clicked()), this, SLOT(onQuit()));

thread.start();
}

signals:
void mySignal(int n);
void mySignalForQueued(int n);

private slots:
void onCallThreadSlotSig()
{
thread.threadSlot(42);
}

void onCallThreadSlot()
{
emit mySignal(1764);
}

void onCallThreadQueuedSlotSig()
{
emit mySignalForQueued(123);
}

void moveRandomObjectToThread()
{
moveRandomObjToThread->setEnabled(false);
obj.moveToThread(&thread);
}

void onQuit()
{
thread.quit();
bool cleanFinish = thread.wait(2000);
if (!cleanFinish)
{
qDebug() << "Impossible d'arrêter le thread, terminaison forcée.\n";
thread.terminate();
}

qApp->quit();
}

private:
MyThread thread;
RandomObject obj;
QPushButton * moveRandomObjToThread;
};

int main(int argc, char **argv)


{
QApplication app(argc, argv);
Window w;
w.show();

return app.exec();
}

- 78 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

#include "main.moc"

Cet exemple produira une sortie semblable à ceci.

MyThread::threadSlot(int), appel depuis le thread # 0xa28 : n= 4


MyThread::threadSlot(int), appel depuis le thread # 0xa24 : n= 1764
MyThread::threadSlot(int), appel depuis le thread # 0xa24 : n= 42

Le slot qui nous intéresse est ici MyThread::threadSlot(int). Il est appelé 3 fois dans ce programme.

• Dans void MyThread::run(), threadSlot() est exécuté dans le contexte du thread exécutant run(), car appelé
directement ;
• Dans void Window::onCallThreadSlot(), threadSlot() est exécuté dans le contexte du thread principal, car
appelé directement depuis celui-ci ;
• Dans void Window::onCallThreadSlotSig(), threadSlot() est exécuté dans le contexte du thread principal, car
appelé indirectement par l'émission d'un signal à partir de ce thread.

Comment utiliser le système de signaux et de slots avec des threads ?


Auteurs : Yan Verdavaine ,
Il n'y a pas vraiment de meilleure solution. Mais voici une version qui utilise QThread comme une sorte de passerelle
de signaux et de slots. Pour cela, on utilise la possibilité de connecter un signal à un signal.

La technique est très simple. L'instance de QThread

• Ne possède aucun slot, car elle ne doit pas accéder aux objects manipulés par le thread ;
• Définira, au besoin, des signaux dans sa définissions de base, appelés des signaux sortantd ;
• Définira, au besoin, à la place des slots, des signaux qui serviront de passerelle vers les slots des objets utilisés
par le thread, appelés des signaux entrant ; dans ce cas il faut utiliser la boucle d'événements.

#include <QtCore>
// Simple class qui émet toutes les secondes un entier incrémenté
// Comme un signal est thread safe, le thread appelera le signal de QThread
class threadEmetteur : public QThread
{
Q_OBJECT
protected:
void run()
{
int i=0;
forever
{
sleep(1);
qDebug()<<"Emission de " << i << " depuis le thread " << (int) currentThreadId();
emit unEntier(i++);
}
}
signals:
// Émet un entier
void unEntier(int);
};

// Le second thread doit recevoir des signaux :


// on crée donc une classe qui sera utilisé en interne au second thread
// et connectée aux signaux entrants
class interthreadReceveur : public QObject

- 79 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

{
Q_OBJECT

public slots:
// Slot qui affichera un entier reçu
void afficheEntier(int i)
{
qDebug() << "Recu " << i << " depuis le thread " << (int) QThread::currentThreadId();
}
};

// Le second thread doit recevoir des signaux et les renvoie vers un objet interne
class threadReceveur : public QThread
{
Q_OBJECT

protected:
void run()
{
// Création de l'objet interne
interthreadReceveur receveur;
// Connexion des signaux entrant vers les slots d'exécutions
connect(this,SIGNAL( afficheEntier(int)),&receveur,SLOT( afficheEntier(int)));
// Lancement de la boucle d'événements
exec();
}

signals:
// Signal entrant qui sera redirigé vers l'objet interne
void afficheEntier(int i);

};

#include "main.moc"
int main(int argc,char**argv)
{
QCoreApplication app(argc,argv);
threadEmetteur te;
threadReceveur tr;
// Connexion d'un signal sortant vers un signal sortant
QObject::connect(&te,SIGNAL( unEntier(int)),&tr,SIGNAL(afficheEntier(int)));

tr.start();
te.start();
return app.exec();
}

On pourrait être tenté d'utiliser la fonction moveToThread sur le QThread en début du run()
pour exécuter ses slots dans le thread. Seulement, cela poserait des problèmes : par exemple,
pour redémarrer le thread après une première exécution, si vous utilisez start() comme un slot.

Comment récupérer et utiliser l'objet déclencheur d'un slot ?


Auteurs : Niak74 ,
Dans un slot, la méthode sender() retourne le QObject qui a déclenché ce slot via un signal (peu importe lequel).

Prenons un exemple.

monSlot est un slot personnalisé de la classe MaClasse.

MaClasse::MaClasse()

- 80 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

{
QPushButton * btn = new QPushButton("bouton");
QObject::connect(btn, SIGNAL(clicked()), this, SLOT(monSlot()));
}

MaClasse::monSlot()
{
QObject * emetteur = sender();
// emetteur contient le QPushButton btn si on clique sur ce bouton
}

Entendu, mais que faire de ce QObject ? C'est le QPushButton que l'on voulait !

Pas de panique ! Pour accéder pleinement à l'émetteur, la prochaine étape est de le caster. Voyons comment faire ça
proprement avec qobject_cast.

MaClasse::monSlot()
{
QObject * emetteur = sender();

// On caste le sender en ce que nous supposons qu'il soit


QPushButton * emetteurCasted = qobject_cast<QPushButton*>(emetteur);

// On teste la réussite du cast avant de procéder à un quelconque accès dessus !


if(emetteurCasted) //emetteurCasted vaut 0 si le cast à échoué
{
// Suite du traitement
}
}

Cette méthode ne fonctionne pas en multithread ! Si l'émetteur et le récepteur ne sont pas dans
le même thread, sender() ne renvoie rien (0). Dans ce cas, vous devez utiliser QSignalMapper

lien : Comment récupérer et utiliser l'objet déclencheur d'un slot avec QSignalMapper ?

Comment récupérer et utiliser l'objet déclencheur d'un slot avec QSignalMapper ?


Auteurs : Niak74 ,
Une alternative à Comment récupérer et utiliser l'objet déclencheur d'un slot ? sender() est l'utilisation d'un
QSignalMapper. Cette classe permet d'associer un signal sans paramètre d'un objet à un autre signal pourvu d'un
paramètre défini. Ce paramètre peut être de type int, QString, QWidget* ou QObject*.

Voici un exemple simple d'utilisation, issu de la documentation Qt.

Dans le cas présent, on a une liste de boutons, contenant du texte, créée à partir d'une liste de QString. On souhaite lier
l'action de presser un bouton (signal clicked()) à un signal qui contient le texte de ce bouton (signal clicked(QString)).

class ButtonWidget : public QWidget


{
Q_OBJECT

public:
ButtonWidget(QStringList texts, QWidget *parent = 0);

signals:
void clicked(const QString &text);

private:
QSignalMapper *signalMapper;

- 81 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

};

ButtonWidget::ButtonWidget(QStringList texts, QWidget *parent)


: QWidget(parent)
{
signalMapper = new QSignalMapper(this);

QGridLayout *gridLayout = new QGridLayout;


// Création de chaque bouton à partir de la liste de mots
for (int i = 0; i < texts.size(); ++i) {
QPushButton *button = new QPushButton(texts[i]);
// On connecte le signal du clic de button au slot map du QSignalMapper
connect(button, SIGNAL(clicked()), signalMapper, SLOT(map()));
// On précise au QSignalMapper que button est associé au texte texts[i]
signalMapper->setMapping(button, texts[i]);
// On place button dans un gridlayout
gridLayout->addWidget(button, i / 3, i % 3);
}

// On connecte le QSignalMapper au signal clicked(const QString &)


connect(signalMapper, SIGNAL(mapped(const QString &)),
this, SIGNAL(clicked(const QString &)));

setLayout(gridLayout);
}

Voici comment fonctionne cet exemple.

On connecte le signal déclencheur souhaité de chaque objet avec le slot map() du QSignalMapper.

On indique au QSignalMapper des liens entre des objets et des paramètres via la méthode setMapping() (ici de type
QString, mais on peut aussi le faire avec des int, QObject* ou QWidget*).

A chaque appel au slot map(), le QSignalMapper identifie l'entité qui déclenche le slot map() (sender()), cherche si cette
entité est liée à un paramètre, et émet le signal mapped() avec le paramètre trouvé.

lien : Comment récupérer et utiliser l'objet déclencheur d'un slot ?

- 82 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sommaire > QtCore > Plug-ins


Qu'est-ce qu'un plug-in ?
Auteurs : Thibaut Cuvelier ,
Un plug-in est un fichier chargé par Qt pour apporter de nouvelles fonctionnalités, soit à Qt lui-même, soit à une
application. Un plug-in peut être directement lié à une application (édition statique des liens) ou bien chargé à
l'exécution.

Il existe deux API de niveau différent pour la création de plug-ins. Une API de haut niveau, pour les plug-ins pour Qt,
et une API de bas niveau pour les applications.

Toute une série de types de plug-ins est réservée à Qt Embedded Linux, parce que Qt peut alors fonctionner sur une
panoplie de matériel différent, qui ne s'utilise pas de la même manière.

Tous les plug-ins sont rangés dans un répertoire, subdivisé en autant de répertoires qu'il y a de type de plug-ins.

• accessible : accessibilité (qui complète un widget) ;


• decorations : style pour Qt Embedded Linux ;
• fontengines : police pour Qt Embedded Linux ;
• iconengines : chargeur d'icônes ;
• imageformats : chargeur d'images ;
• inputmethods : méthode d'entrée (qui convertit des combinaisons de touches en une chaîne de caractères) ;
• kbddrivers : clavier pour Qt Embedded Linux ;
• mousedrivers : souris pour Qt Embedded Linux ;
• pictureformats : ce type de plug-in est déprécié ;
• gfxdrivers : écran pour Qt Embedded Linux ;
• script : extension de Qt Script ;
• sqldrivers : moteur SQL ;
• styles : style ;
• codecs : suppport d'alphabets non latins.

Les plug-ins ne sont pas chargés automatiquement : si Qt a besoin d'un plug-in pour lire un format d'image qui n'est pas
supporté nativement, il va demander aux plug-ins les formats qu'ils peuvent lire. Si l'un d'entre eux semble convenir, il
est chargé complètement. Si vous ne lisez pas la moindre image dans votre application, aucun plug-in de lecture d'images
ne sera chargé.

Qu'est-ce que la buildkey ?


Auteurs : Thibaut Cuvelier ,
Pendant la compilation de Qt, une buildkey est définie. Elle contient, entre autres, l'architecture (IA32, IA64, AMD64...),
l'OS et sa version (Windows 6.0, Linux 2.6...), le compilateur et sa version (GCC 4.4.0, Visual C++ 9.0...), la configuration
de Qt (les drapeaux passés lors de la compilation) et une clé optionnelle, spécifiée lors de la compilation (-buildkey).

Pourquoi ? Tous les environnements influencent fortement la manière de produire des binaires. Deux configurations
de Qt différentes ne sont pas forcément compatibles ! Pour éviter tous les désagréments qui peuvent être causés par ces
différences (cela peut aller de aucun problème à un plantage lamentable du système), Qt vérifie que tous les binaires
sont parfaitement compatibles.

- 83 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Lorsque vous lancez votre application Qt, ce dernier commence par s'initialiser. Il vérifie que la buildkey de votre
application correspond à la buildkey de Qt. Ensuite, lors du chargement de chaque module, cette vérification est aussi
effectuée. De même lors du chargement de chaque plug-in.

Qt tient un cache avec toutes ces informations. Ce cache est réactualisé à chaque changement d'un des fichiers. Ceci
permet d'éviter de recharger l'entièreté des fichiers à chaque fois, et d'ainsi gagner du temps. Ce cache est géré par
QSettings, son emplacement change donc en fonction de l'OS.

Par exemple, sous Windows, il se situe dans le registre à cet emplacement : HKEY_CURRENT_USER\Software
\Trolltech\OrganizationDefaults\.

Pour être beaucoup plus précis, Qt pourra charger des plug-ins pour d'autres versions, mais à quelques conditions :
que le plug-in ait été compilé avec une version antérieure de Qt, mais de la même branche. S'il a été compilé avec Qt
3, il ne fonctionnera pas avec une application Qt 4. S'il a été compilé avec Qt 4.5.1, et que l'application l'a été avec Qt
4.5.0, ça ne fonctionnera pas. Par contre, s'il a été compilé avec la version 4.5.0, et que l'application a été compilée avec
Qt 4.5.1, ça fonctionnera. Sauf si une buildkey additionnelle a été précisée lors de la compilation de Qt : il faudra que le
plug-in soit compilé avec une version compatibles (donc antérieure) et ait la même buildkey additionnelle.

- 84 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sommaire > QtCore > Temps


Comment utiliser un QTimer ?
Auteurs : François Jaffré ,
Les timers sont gérés avec Qt à l'aide de la classe QTimer. Cette classe est relativement simple à utiliser grâce aux
méthodes suivantes :

- 85 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

• int interval () const : permet de connaitre l'intervalle de temps (en ms) entre chaque déclanchement du timer.
• bool isActive () const : permet de connaitre si le timer est activé ou pas.
• bool isSingleShot () const : permet de connaitresi le timer est en déclanchement unique ou pas.
• void setInterval ( int msec ) : permet de paramétrer l'intervalle (en ms) entre chaques déclanchements du timer
• void setSingleShot ( bool singleShot ) : permet de mettre le timer en mode déclanchement unique
• void start () : permet de démarrer le timer
• void stop () : permet d'arrêter le timer

Création d'un chronomètre simple précis à la seconde


#include <QApplication>
#include <QLCDNumber>
#include <QPushButton>
#include <QTimer>
#include <QGridLayout>

class TimerChrono : public QWidget


{
Q_OBJECT

private :
// Bouton servant de "Start" "Stop"
QPushButton* m_Bouton_StartStop;
// Bouton "Reset"
QPushButton* m_Bouton_Reset;
// Afficheur de type LCD
QLCDNumber* m_LCD;
// Variable représentant le nombre de secondes écoulées depuis le lancement du timer
int m_Timer_value;
// Timer servant de base à notre Chronomètre
QTimer* m_timer;
// Permet de savoir si l'utilisateur a cliqué sur "Start" ou "Stop"
bool validStart;

public :
TimerChrono()
{
// Création d'un afficheur LCD de 5 digits maximum
this->m_LCD = new QLCDNumber(5, this);
// Création des contrôles de type bouton
this->m_Bouton_StartStop = new QPushButton("Start",this);
this->m_Bouton_Reset = new QPushButton("Reset",this);

// Gestion du layout pour le placement des boutons


QGridLayout *layout = new QGridLayout();
layout->addWidget(m_LCD, 0, 0);
layout->addWidget(m_Bouton_StartStop, 2,0);
layout->addWidget(m_Bouton_Reset, 2,1);
this->setLayout(layout);

// On met à zéro le compteur représentant le nombre de seconde


this->m_Timer_value=0;
// Création du timer
this->m_timer = new QTimer(this);
// À chaque fin d'intervale, exécution du slot update()
connect(this->m_timer, SIGNAL(timeout()), this, SLOT(update()));
// On applique un intervale d'une seconde (1000 ms) entre chaque timeout du timer
this->m_timer->setInterval(1000);
// Sert pour la gestion du bouton "Start" "Stop"
this->validStart=true;

// On connecte les différents signaux et slots


connect(this->m_Bouton_StartStop, SIGNAL(clicked(bool)), this, SLOT(click_StartStop(bool)));
connect(this->m_Bouton_Reset, SIGNAL(clicked(bool)), this, SLOT(click_Reset(bool)));

// Gestion de la taille de la fenêtre

- 86 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Création d'un chronomètre simple précis à la seconde


resize(200, 150);
}

private slots:
// Fonction appelée toute les secondes par le QTimer
void update()
{
// On incrémente notre compteur de secondes
m_Timer_value++;
// On affiche le nombre de secondes écoulées dans le contrôle QLCDNumber
m_LCD->display(m_Timer_value);
}

// Bouton reset
void click_Reset(bool valid)
{
// On arrête le timer
this->m_timer->stop();
// On met notre compteur à zéro
m_Timer_value=0;
// On affiche zéro dans le controle LCD
m_LCD->display(m_Timer_value);
// Gestion du bouton "Start" "Stop"
this->validStart=true;
m_Bouton_StartStop->setText("Start");
}

// Bouton "Start" "Stop"


void click_StartStop(bool valid)
{
//Si on clique sur "Start"
if(validStart == true)
{
// Affiche "Stop" sur le bouton
m_Bouton_StartStop->setText("Stop");
// Permet de savoir que le bouton est en mode "Stop"
validStart = false;
// On déclenche le départ du Timer
this->m_timer->start();
}
// Si on clique sur "Stop"
else
{
// Affiche "Sart" sur le bouton
m_Bouton_StartStop->setText("Start");
// Permet de savoir que le bouton est en mode "Start"
validStart = true;
// On arrete le compteur
this->m_timer->stop();
}
}
};

#include "main.moc"

int main(int argc, char *argv[])


{
QApplication a(argc, argv);
TimerChrono w;
w.show();
return a.exec();
}

Remarque 1 : Si vous souhaitez utiliser un timer en mode "single shot" QTimer possède une méthode statique
QTimer::singleShot(), qui peut vous être très utile.

- 87 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Remarque 2 : Un timer n'est jamais très précis et est fortement dépendant de l'OS. Si vous souhaitez être précis à la
milliseconde, ce n'est pas la solution à utiliser.

Comment récupérer l'heure du PC ?


Auteurs : François Jaffré ,
La classe QTime permet de récupérer l'heure de l'ordinateur facilement à l'aide de la méthode statique suivante :

QTime QTime::currentTime() permet de récupérer un objet QTime initialisé à l'heure courante.

//L'objet time est initialisé à l'heure courante


QTime time = QTime::currentTime();

Comment mesurer un intervalle de temps ?


Auteurs : François Jaffré ,
QTime fournit la méthode elapsed() qui permet de connaitre le temps écoulé (en ms) entre l'exécution de la méthode
start() ou restart() et l'appel à la fonction elapsed().

QTime time;
time.start();
ma_fonction();
// millisecondes contient le nombre de millisecondes entre l'appel à la fonction start()
// et l'appel 0 la fonction elapsed()
int millisecondes = time.elapsed();

Remarque : si vous voulez vraiment mesurer précisément votre code et faire du benchmarking de votre application,
alors il est préférable de vous tourner vers QTestLib, qui est faite pour ça.

Comment convertir un QDate en QString ?


Auteurs : Niak74 ,
QDate (et QDateTime, qui contient en plus QTime) permet de manipuler la date.

Qt nous propose une manière sympathique de convertir en chaîne de caractères les données contenues par un QDate
via la méthode toString(QString& format). Grâce à l'argument format, il nous est possible de d'indiquer le format de
cette chaîne de caractères. Cet argument peut se composer de ces différents sigles.

Les sigles utilisables pour QDate


• d : le numéro du jour (1 à 31),
• dd : le numéro du jour écrit avec deux chiffres (01 à 31),
• ddd : l'abréviation du jour ('Lun' à 'Dim'), utilise QDate::shortDayName(),
• dddd : le jour ('Lundi' à 'Dimanche'), utilise QDate::longDayName(),
• M : le numéro du mois (1 à 12),
• MM : le numéro du mois écrit avec deux chiffres (01 à 12),
• MMM : l'abréviation du mois ('Jan' à 'Dec'), utilise QDate::shortMonthName(),
• MMMM : le mois ('Janvier' à 'Décembre'), utilise QDate::longMonthName(),

- 88 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

• yy : les deux derniers chiffres de l'année (00 à 99),


• yyyy : l'année en quatre chiffres (peut être négatif, - est alors ajouté),

La date contenue par QDate date est le 20 juillet 1969.

date.toString("dd.MM.yyyy") // Retourne "20.07.1969"


date.toString("ddd d MMMM yy") // Retourne "dimanche 20 Juillet 69"
date.toString("'Nous sommes ' dddd") // Retourne "Nous sommes dimanche"

Comme nous pouvons le constater avec le troisième exemple, il est possible d'ajouter du texte personnalisé dans
l'argument de la méthode toString(). Ce texte doit être entouré par des ' (apostrophe) et sera restitué dans le résultat,
à la position indiquée.

Pour afficher le caractère ' (apostrophe), il faut écrire '' (deux apostrophes consécutives).

lien : Comment convertir un QTime en QString ?


lien : Comment choisir la langue dans laquelle afficher le QString ?

Comment convertir un QTime en QString ?


Auteurs : Niak74 ,
QTime (et QDateTime, qui contient en plus QDate) permet de manipuler l'heure.

Qt nous propose une manière sympathique de convertir en chaîne de caractères les données contenues par un QTime
via la méthode toString(QString& format). Grâce à l'argument format, il nous est possible de d'indiquer le format de
cette chaîne de caractères. Cet argument peut se composer de ces différents sigles.

Les sigles utilisables pour QTime


• h : l'heure (0 à 23 ou 1 à 12 si affichage en AM/PM),
• hh : l'heure sur deux chiffres (00 à 23 ou 01 à 12 si affichage en AM/PM),
• H : l'heure (0 à 23, même si affichage en AM/PM),
• HH : l'heure sur deux chiffres (00 à 23, même si affichage en AM/PM),
• m : la minute (0 à 59),
• mm : la minute en deux chiffres (00 à 59),
• s : la seconde (0 à 59),
• ss : la seconde en deux chiffres (00 à 59),
• z : la milliseconde (0 à 999),
• zzz : la milliseconde en trois chiffres (000 à 999),
• AP ou A : affichage en AM/PM. Affiche AM ou PM à la place de AP,
• ap ou a : affichage en am/pm. Affiche am ou pm à la place de ap.

L'heure contenue par QTime heure est 14:13:09.042 (14 heures, 13 minutes, 9 secondes et 42 millièmes de seconde).

heure.toString("hh:mm:ss.zzz") // Retourne "14:13:09.042"


heure.toString("h:m:s ap") // Retourne "2:13:9 pm"
heure.toString("H:m:s a") // Retourne "14:13:9 pm"

lien : Comment convertir un QDate en QString ?

- 89 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

lien : Comment choisir la langue dans laquelle afficher le QString ?

Comment choisir la langue dans laquelle afficher le QString ?


Auteurs : Niak74 ,
Pour ce faire, il faut utiliser la classe QLocale et ses différentes implémentations de la méthode toString(). Voici celles
qui nous intéressent :

• QString QLocale::toString ( const QDate & date, const QString & format ) const
• QString QLocale::toString ( const QTime & time, const QString & format ) const

Il est possible de ne pas définir de format, auquel cas Qt affichera la date au format classique
du pays.

On suppose que la date est définie dans la variable QDate date. On choisit le format d'écriture ddd d MMMM yy.

QLocale francais("fr_FR");
francais.toString(date, "ddd d MMMM yy"); //Affiche la date en français

QLocale anglaisUS("en_US");
anglaisUS.toString(date, "ddd d MMMM yy"); //Affiche la date en anglais (Etats-Unis).

QLocale anglaisGB("en_GB");
anglaisGB.toString(date, "ddd d MMMM yy"); //Affiche la date en anglais (Royaume-Uni).

QLocale coreen("ko");
coreen.toString(date, "ddd d MMMM yy"); //Affiche la date en coréen

QLocale allemandSuisse("de_CH");
allemandSuisse.toString(date, "ddd d MMMM yy"); //Affiche la date en allemand (Suisse)

lien : Comment convertir un QDate en QString ?


lien : Comment convertir un QTime en QString ?

- 90 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sommaire > QtCore > Événements


Comment manipuler les événements de Qt?
Auteurs : Yan Verdavaine ,
Les QObject possèdent un système d'événements. Ceci leur permet de définir des actions en fonction de certain type
d'évènement qu'ils reçoivent. Par exemple, à la fin d'un timer ou lors d'un paint sur un widget.
Il est donc très important de pouvoir les manipuler. Pour cela, il existe deux méthodes :

1 - La surcharge de fonction
Lors qu'un QObject reçoit un événement, celui-ci passe par la fonction bool QObject::event(QEvent *). C'est le point
d'entrée lorsque un évènement arrive sur un QObject. Cette fonction va ensuite vérifier le type de l'évènement et
appeler une sous-fonction liée à ce type. Toutes ces fonctions ont pour signature void XXXEvent(QXXXEvent *) et
sont principalement définies dans QObject et QWidget. Par exemple, si l'évènement est un QPaintEvent, la fonction
paintEvent() sera appelée. Il suffit donc de choisir la méthode à surcharger suivant l'événement avec lequel on veut
interagir.

Par exemple, comment tracer une courbe en fonction des clics de souris ?

#include <QtGui>

class MonWidget : public QWidget


{
// points cliqués
QVector<QPoint> m_points;
protected :
// ajout du point cliqué lors de l'événement "bouton de la souris relaché".
void mouseReleaseEvent(QMouseEvent *qevent)
{
m_points << qevent->pos();
update();
}
// affichage d'un polyligne formé par les points lors de l'évènement "repaint"
void paintEvent(QPaintEvent *qevent)
{
QPainter p(this);
p.drawPolyline(m_points);
}
};

int main (int argc, char * argv[])


{
QApplication app(argc,argv);
MonWidget w;
w.resize(300,300);
w.show();
return app.exec();
}

2 - Event filter
Cette méthode consiste à installer un filtre d'évènements sur un QObject. Ce filtre d'évènements est en réalité un
QObject. Cette méthode a l'avantage d'éviter des héritages inutiles et de pouvoir manipuler les évènements d'un ou
plusieurs autres QObject.

Pour qu'un QObject puisse être utilisé comme filtre, il doit surcharger la méthode bool QObject::eventFilter(QObject
*obj, QEvent *event). Cette méthode prend en paramètre un QObject correspondant au QObject à filtrer et un QEvent,
son événement. Si la fonction retourne vrai, l'évènement s'arrête et le QObject ne traitera pas son événement. Si la
fonction retourne faux, l'événement sera traité par le QObject.

- 91 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Ensuite, il suffit d'appeler la méthode installEventFilter(QObject *) du QObject à filtrer avec pour paramètre le
QObject servant de filtre.

#include <QtGui>

class MonWidget : public QWidget


{
// points cliqués
QVector<QPoint> m_points;
protected :
// filtre
bool eventFilter(QObject *obj, QEvent *qevent)
{
//vérifie que le QObject est une QFrame
//et que le type d'év&nement est "bouton de la souris relaché"
QFrame * f = qobject_cast<QFrame *>(obj);
if(f && qevent->type() == QEvent::MouseButtonRelease)
{
//on sait déjà que c'est un QMouseEvent, donc un static_cast suffit
QMouseEvent *mevent = static_cast<QMouseEvent *> (qevent);
m_points << mevent->pos();
update();
}
//on appelle la fonction du parent
return QWidget::eventFilter(obj,qevent);
}
// affichage d'un polyligne formé par les points lors de l'évènement "repaint"
void paintEvent(QPaintEvent *qevent)
{
QPainter p(this);
p.drawPolyline(m_points);
}
};

int main (int argc, char * argv[])


{
QApplication app(argc,argv);
//création d'un widget avec deux zones :
// * une Frame pour cliquer
// * un MonWidget pour l'affichage
QWidget w ;
MonWidget *mW = new MonWidget;
QHBoxLayout * l = new QHBoxLayout(&w);
QFrame * f = new QFrame;
{
//l'intance de MonWidget va servir de filtre
//sur les événements de la frame
f->installEventFilter(mW);
f->setFrameShape (QFrame::StyledPanel);
l->addWidget(f);
}
l->addWidget(mW);
w.resize(300,300);
w.show();
return app.exec();
}

la méthode par la surcharge de fonctions est utiliséé pour manipuler les évènements du
QObject par lui même. Tandis que la méthode avec les filtres d'événements est surtout utilisée
pour filtrer et interagir avec les événements d'un autre QObject.

- 92 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sommaire > QtCore > Ressources


Comment intégrer des ressources à mon application ?
Auteurs : Thibaut Cuvelier ,
Les ressources sont des fichiers que l'on peut insérer dans un exécutable. Ils seront disponibles depuis l'exécutable, sans
devoir être distribués avec l'exécutable.

Il y a deux manières d'insérer les ressources : soit directement dans l'exécutable, soit dans un fichier de ressources
binaire. Dans les deux cas, un fichier QRC doit être utilisé, et compilé avec RCC.

Voici un exemple de fichier QRC.

<!DOCTYPE RCC> <RCC version="1.0">


<qresource>
<file>images/copy.png</file>
<file>images/cut.png</file>
</qresource>
</RCC>

Vous pouvez intégrer ces fichiers dans l'exécutable : il suffit d'indiquer, dans votre fichier de projet, le fichier de
ressources, et qmake s'occupe, encore une fois, de tout.

RESOURCES = application.qrc

Vous pouvez facilement accéder aux fichiers mentionnés dans le QRC :

cutAct = new QAction(QIcon(":/images/cut.png"), tr("Cu&t"), this);

Cette méthode ne fonctionne pas toujours. Voici un exemple où vous êtes obligé d'utiliser la méthode alternative.

QString text = "<h1 style='background: url(qrc:/Images/Fond.png) repeat-x;'>Ceci est un titre !</


h1>";
QWebView *navigator = new QWebView(this);
navigator->setHtml(text);

Vous pouvez aussi compiler le fichier de ressources pour avoir un fichier de ressources binaire.

rcc -binary myresource.qrc -o myresource.rcc

Avant de pouvoir utiliser le fichier créé dans votre application, il faudra l'enregistrer.

QResource::registerResource("/path/to/myresource.rcc");

Avec cette ligne, vous pourrez utiliser les ressources contenues dans le fichier binaire comme n'importe quelle ressource.

Les ressources peuvent être facilement localisées.

<qresource>
<file>cut.jpg</file>
</qresource>
<qresource lang="fr">
<file alias="cut.jpg">cut_fr.jpg</file>
</qresource>

- 93 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Quand la langue de l'application sera le français, les références à :/cut.jpg seront redirigées vers :/cut_fr.jpg.

- 94 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sommaire > QtGui


Comment dessiner dans un QWidget ?
Auteurs : Yan Verdavaine ,
Lorsqu'un widget doit être dessiné ou redessiné, la fonction protégée QPaintEvent est appelée. Pour se dessiner, la
majorité des widgets de Qt utilise un QPainter lors de l'appel à cette fonction. Il est donc naturel de suivre cette logique.

L'évènement QPaintEvent passé en paramètre indique la zone à redessiner. Cette zone est donnée sous forme de
rectangle QPaintEvent::rect ou sous forme quelconque QRegion. Ces informations peuvent être utilisées pour optimiser
l'affichage du widget.

La classe QPainter est un outil qui permet de dessiner sur toutes les classes graphique de Qt :
QCustomRasterPaintDevice, QGLFramebufferObject, QGLPixelBuffer, QImage, QPicture, QPixmap, QPrinter,
QSvgGenerator, et QWidget.

Cette classe utilise d'autres outils de Qt. Les plus importants, à mon avis, sont :

• QPen : caractérise le contour d'une forme (ligne, point, contour d'une forme...) ;
• QBrush : caractérise l'intérieur d'une forme (intérieur d'un rectangle...).

Voici un exemple.

Dessiner sur un widget


#include <QtGui>

class MyTest : public QWidget


{
public:
MyTest ( QWidget * parent = 0, Qt::WindowFlags f = 0 ) : QWidget (parent,f){};
void paintEvent ( QPaintEvent * event )
{
//creation d'un QPainter
//QPen : aucun contour
//QBrush : aucun remplissage
QPainter painter(this);

//On definie au QPainter un stylo rouge de taille 4


QPen pen;
pen.setColor (Qt::red);
pen.setWidth (4);
painter.setPen(pen);

//On dessine un rectangle


//QPen : rouge de taille 4
//QBrush : aucun remplissage
painter.drawRect (10, 10, 80, 80);

//on definie au QPainter un pinceau vert utilisant le pattern SOLID


QBrush brush(Qt::SolidPattern);
brush.setColor(Qt::green);
painter.setBrush(brush);

//on dessine un rectangle


//QPen : rouge de taille 4
//QBrush : remplissage vert avec le pattern SOLID
painter.drawRect (15, 15, 70, 70);

//on definie au QPainter stylo bleu de taille 8

- 95 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Dessiner sur un widget


pen.setColor (Qt::blue);
pen.setWidth (8);
painter.setPen(pen);

//dessine une ligne


//QPen : bleu de taille 8
//QBrush : n'est pas utilise pour une ligne
painter.drawLine(0, 0, 100, 100);
}
};

int main(int argc, char* argv[])


{
QApplication app(argc, argv);
MyTest win;
win.resize(100, 100);
win.show();
return app.exec();
}

Pourquoi je n'arrive pas à dessiner sur n'importe quels widgets ?


Auteurs : Yan Verdavaine ,
Certains widgets sont basés sur QAbstractScrollArea, dont le but est de permettre l'affichage d'un widget plus grand
que sa zone d'affichage, en ajoutant des barres de défilement, par exemple. Appliquer un painter directement sur celle-
ci n'aura pas l'effet souhaité. Cette classe implémente la méthode viewport() qui permet d'accéder au widget qui est
réellement affiché. Il faut donc appliquer le painter sur celui-ci.

On constate ainsi trois étapes lors de la redéfinition du paintevent :


• Pre-dessin : le dessin en arrière plan
• Dessin originel : le dessin d'origine.
• Post-dessin : le dessin au premier plan.

Les widgets concernés sont QAbstractItemView, QGraphicsView, QMdiArea, QPlainTextEdit,


QScrollArea, QTextEdit, QTextBrowser, QColumnView, QHeaderView, QListView, QTableView, QTreeView,
QHelpContentWidget, QTreeWidget, QTableWidget, QHelpIndexWidget, QListWidget, QUndoView.

Dessiner avec un QListView


#include <QtGui>

class myListView : public QListView


{
public:
myListView()
{}

protected:
void paintEvent(QPaintEvent *event)
{
/*pre-dessin*/
if (this->viewport())
{
QPainter painter(this->viewport());
painter.setBrush(QBrush(Qt::green, Qt::SolidPattern));
painter.drawRect(QRect(0,0,50,50));
}

/*dessin originel*/

- 96 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Dessiner avec un QListView


QListView::paintEvent(event);

/*post-dessin*/
if (this->viewport())
{
QPainter painter(this->viewport());
painter.setBrush(QBrush(Qt::red, Qt::SolidPattern));
painter.drawRect(QRect(25,25,50,50));
}
event->accept();
}
};

int main(int argc, char **argv)


{
QApplication app(argc, argv);
QStringList list;
list<<"dessiner"<<"avec"<<"un"<<"QListView";

myListView w;
w.setModel(new QStringListModel(list,&w));
w.show();
return app.exec();
}

Remarque : Comme le traitement avant-dessin se dessine en arrière plan, il peut être totalement effacé par le dessin
originel ou le post-dessin.

Comment ajouter un lien vers une page HTML ?


Auteurs : Yan Verdavaine ,
La façon la plus simple est d'utiliser un QLabel et ses possibilités de Rich text. Pour cela il suffit :

a D'autoriser l'ouverture vers une page web


b De remplir le label avec un petit morceau en HTML : <a href='site referencé'>XXXXX</a>, où XXX peut être :
• Une phrase simple,
• Une phrase en HTML : <font size='S' family='...' color='C'> ... </font>
• size : taille de la police (facultatif) ;
• family : police à utiliser, dans l'ordre de préférence (facultatif) ;
• color : couleur du texte.
• Il est possible de compléter la phrase en utilisant les balises de formatage de texte comme gras
(<b>...<\b>), italique (<i>...</i>)...
• Une image en HTML : <img src='MON_IMAGE' height ='H' width= 'W'>
• src : path de l'image à afficher (peut se situer dans les ressources) ;
• height : hauteur de l'image (facultatif) ;
• width : largeur de l'image (facultatif).

Exemple avec un lien text et un lien image


#include <QtGui>

int main(int argc, char* argv[])


{
QApplication app(argc, argv);
QLabel label;
//on ecrit un petit bout de html
label. setText ( "La doc de"

- 97 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Exemple avec un lien text et un lien image


// Lien par un texte HTML
"<a href='http://qt.nokia.com/doc/qlabel.html'>"
"<font size='15' family='Arial, Helvetica, sans-serif'
color='green'><b> Qt </b></font>"
"</a>"
"et voici "
// Lien par une image
"<a href='http://qt.developpez.com/faq/'>"
"<img src='FAQ-Qt.gif'>"
"</a>");
// On autorise l'ouverture du lien vers le viewer par défaut
label.setOpenExternalLinks ( true );
label.show();
return app.exec();
}

Comment créer une page d'accueil ?


Auteurs : Shugo78 ,
Qt propose la classe QSplashScreen pour simplifier la gestion des pages de démarrage. Une page de démarrage est
une image affichée lors du démarrage d'un programme, pour masquer un démarrage lent ou tout simplement par
marketing.

Remarque :

• Cette page se fermera si l'on clique dessus ;


• QSplashScreen est lancé avant la boucle d'événement de l'application, il est donc préférable d'appeler
QApplication::processEvents() de temps en temps pour traiter les événements en cours.

#include <QtGui>
#include <windows.h> //Sleep

int main (int argc, char** argv)


{
QApplication app (argc, argv);

// Création de la page de démarrage


QSplashScreen splash;
// La page sera devant toutes les fenêtres
splash.setWindowFlags ( Qt::WindowStaysOnTopHint);
splash.setPixmap(QPixmap ("c:/figure1.jpg"));
splash.show();

// On écrit sur l'image l'étape en cours


splash.showMessage (QObject::tr ("Etape 1"), Qt::AlignRight | Qt::AlignTop, Qt::white);
// On simule un traitement de durée 2s
// /!\ pour Windows
Sleep(2000);
// On lance un traitement sur les événements
app.processEvents();

// On change l'image
splash.setPixmap(QPixmap ("c:/figure2.jpg"));
// On écrit sur l'image l'étape en cours
splash.showMessage (QObject::tr ("Etape 2"), Qt::AlignRight | Qt::AlignTop, Qt::white);
// On simule un traitement de durée 2s
// /!\ pour Windows
Sleep(2000);
// On lance un traitement sur les événements

- 98 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

app.processEvents();

QWidget w;
w.show();
// La page se fermera une fois le widget affiché
splash.finish (&w);

return app.exec ();


}

Comment afficher une image dans mon interface ?


Auteurs : Denys Bulant ,
La méthode la plus simple est d'utiliser un QLabel conjointement à un QPixmap.

#include <QtGui>

int main(int argc, char* argv[])


{
QApplication app(argc, argv);
QLabel label;
//on donne l'image au label
label.setPixmap(QPixmap("c :/image.png"));
label.show();
QObject::connect(&label, SIGNAL(clicked()), &app, SLOT(quit()));
return app.exec();
}

Comment dégeler simplement une IHM ?


Auteurs : Yan Verdavaine ,
Si une action longue est exécutée (comme un parcours récursif de répertoire, une copie de plusieurs fichiers...) par
l' IHM, celle ci va se geler et ne plus répondre... Pour remédier à cela, il est souvent préférable d'utiliser un thread.

Mais il existe une alternative intéressante lorsque ce traitement n'a vraiment aucun intérêt à être mis dans un thread :
QCoreApplication (et donc QApplication ) possède la méthode statique processevents() permettant l'exécution d'une
partie ou de tous les événements de la boucles d'événements.

Simulation d'un traitement long : l'un utilise le processevents ; l'autre, non


#include <QtGui>
#include <cmath>
#include <ctime>

// Simule une action


double action_simulation(int nb =1000)
{
double somme(0.);
for (unsigned int j=0;j<nb;++j) somme+=sqrt(static_cast<double>(j));
return somme;
}

class MyQPushButton : public QPushButton


{
public :

- 99 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Simulation d'un traitement long : l'un utilise le processevents ; l'autre, non


MyQPushButton(const QString & text, QWidget * parent = 0)
:QPushButton (text,parent)
{
resize(75, 30);
setFont(QFont("Times", 12, QFont::Bold));
};
protected:
// action lorsque le bouton est relaché
void mouseReleaseEvent ( QMouseEvent * event )
{
// progress bar infinie
QProgressDialog mybar( "Wait ...", 0, 0, 0);
mybar.setWindowModality(Qt::ApplicationModal);
mybar.show();

// simule une action lente de 5s


double somme(0.);
clock_t endwait;
endwait = clock () + 5* CLOCKS_PER_SEC ;
while (clock() < endwait)
{
somme+= action_simulation() ;
}
qDebug()<<somme;
}
};

class MyQPushButton2 : public QPushButton


{
public :
// créateur.
// text : texte du boutton
MyQPushButton2(const QString & text, QWidget * parent = 0)
:QPushButton (text,parent)
{
resize(75, 30);
setFont(QFont("Times", 12, QFont::Bold));
};
protected :
// action lorsque le bouton est relaché
void mouseReleaseEvent ( QMouseEvent * event )
{
// progress bar infinie
QProgressDialog mybar( "Wait ...", 0, 0, 0);
mybar.setWindowModality(Qt::ApplicationModal);
mybar.show();

// simule une action lente de 5s


double somme(0.);
clock_t endwait;
endwait = clock () + 5 * CLOCKS_PER_SEC ;
while (clock() < endwait)
{
QCoreApplication::processEvents();
somme+= action_simulation() ;
}
qDebug()<<somme;
}
};

int main(int argc, char* argv[])


{
QApplication app(argc, argv);
QWidget w;
QVBoxLayout * vl = new QVBoxLayout;
{

- 100 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Simulation d'un traitement long : l'un utilise le processevents ; l'autre, non


//boutton : L'application se bloque pendant le traitement
MyQPushButton * bouton1 = new MyQPushButton("Sans QCoreApplication::processEvents()");

//boutton : L'application ne se bloque pas pendant le traitement


MyQPushButton2 * bouton2 = new MyQPushButton2("Avec QCoreApplication::processEvents()");

vl->addWidget(bouton1);
vl->addWidget(bouton2);
}
w.setLayout(vl);
w.show();
return app.exec();
}

Quel est le rapport entre Item View et Graphics View ?


Auteurs : Benjamin Poulain ,
Il n'y a pas de liens de parenté entre ces deux-là. Au début il arrive de se tromper entre Item View et Graphics View,
simplement car il y a "View" dans les deux noms. Graphics View permet de dessiner et gérer des objets 2D. Item View
permet de gérer des éléments (les items), et de les représenter visuellement (en table, liste et arbre). Rien n'empêche
de combiner ces deux infrastructures, mais il vaut mieux ne pas les confondre pour lire la documentation ou pour
communiquer.

Comment valider des entrées utilisateurs dans une zone d'édition ?


Auteurs : François Jaffré ,
Qt fournit un mécanisme de gestion de la validation et de vérification des entrées utilisateur dans une zone
d'édition. La classe de base est la classe QValidator, dont dérivent les classes QDoubleValidator, QIntValidator, et
QRegExpValidator. L'utilisation de ces classes est très simple, au moins pour les deux premières.

Voici un exemple d'utilisation. On veut limiter l'entrée dans une zone d'édition de nombres entiers compris entre 0 et
100 et uniquement ce type de nombre.

// On définit un objet de type QIntValidator acceptant uniquement des nombre entier entre 0 et 100
QIntValidator* validator = new QIntValidator (0, 100, this);
// Création d'une zone d'édition : ici une QLineEdit
QLineEdit *edit= new QLineEdit(this);
// On applique l'objet QIntValidator à la zone d'edition
edit->setValidator(validator);

Le même principe est utilisable pour contrôler par exemple une valeur double avec QDoubleValidator. Si l'on
souhaite un motif spécifique par exemple une adresse IP, un numéro de téléphone ou autre, il faut utiliser la classe
QRegExpValidator ou créer soi-même un validateur à partir d'une classe dérivant de QValidator.

Comment créer un programme dans la zone de notification ?


Auteurs : François Jaffré ,
Qt, depuis sa version 4.2, permet, grâce à la classe QSystemTrayIcon, de créer facilement des programmes ayant une
entrée dans la zone de notification. Cela se fait à l'aide des quelques méthodes suivantes :

- 101 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

• void setIcon (const QIcon & icon) : permet d'appliquer une image qui servira d'icon dans la zone de notification
• void setContextMenu (QMenu * menu) : permet l'ajout d'un menu quand on fait un click droit sur l'icone se
trouvant dans la zone de notification.
• void showMessage (const QString & title, const QString & message, MessageIcon icon = Information, int
millisecondsTimeoutHint = 10000) : permet l'affichage d'un popup dans la zone de notification.

Exemple
#include >QApplication>
#include <QSystemTrayIcon>
#include <QMenu>
#include <QPushButton>
#include <QHBoxLayout>

class SysTray : public QWidget


{
Q_OBJECT

private :
QSystemTrayIcon* m_SystIcon;
QPushButton* m_Bouton_Message;

public :
SysTray()
{
// Boutou qui nous servira pour l'affichage de l'infobulle
this->m_Bouton_Message = new QPushButton("Affiche text",this);

// Gestion du layout pour l'affichage


QHBoxLayout *layout = new QHBoxLayout();
layout->addWidget(m_Bouton_Message);
this->setLayout(layout);

// Création de l'objet gérant l'entrée dans la zone de notification


m_SystIcon = new QSystemTrayIcon(this);

// Création du menu qui apparaitra après un clic droit sur l'icône


QMenu* sysTrayMenu = new QMenu(this);

// Création des différentes actions pour le menu de la zone de notification


QAction* hide = new QAction("Hide",this);
QAction* show = new QAction("Show",this);
QAction* quit = new QAction("Quit",this);

// On ajoute nos actions au menu système


sysTrayMenu->addAction(hide);
sysTrayMenu->addAction(show);
sysTrayMenu->addAction(quit);

// On lie le menu avec l'icône


m_SystIcon->setContextMenu(sysTrayMenu);

// On charge l'image dans l'object icône


QIcon unIcon("windows.png");

// On place notre image dans la zone de notification


m_SystIcon->setIcon(unIcon);

// Affichage de l'icône dans la zone de notification


m_SystIcon->show();

// On ferme si la personne clique sur "Quit"


connect(quit, SIGNAL(triggered()), this, SLOT(close()));
// On affiche la fenêtre si la personne cliuqe sur "Show"
connect(show, SIGNAL(triggered()), this, SLOT(show()));

- 102 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Exemple
// On cache la fenêtre si la personne clique sur "Hide"
connect(hide, SIGNAL(triggered()), this, SLOT(hide()));
// On affiche une infobulle dans la zone de notification
connect(m_Bouton_Message, SIGNAL(clicked(bool)), this, SLOT(Affiche(bool)));
}

private slots:
void Affiche(bool valid)
{
//Affichage de l'info bulle
m_SystIcon->showMessage
(
"Bravo !",
"Vous venez de créer une application dans la zone de notification !"
);
}

};

#include "main.moc"

int main(int argc, char *argv[])


{
QApplication a(argc, argv);
SysTray w;
w.show();
return a.exec();
}

Remarque : La méthode showMessage() (arrivée à partir de Qt 4.3), qui fait apparaitre une infobulle, est dépendante
des paramètres de l'OS.

lien : QSystemTrayIcon : ajoutez votre programme à la zone de notification avec Qt

Comment réaliser des fenêtres modales et amodales ?


Auteurs : François Jaffré ,
Qt permet, comme tous les framworks gérant les GUI, la création de fenêtres modales (qui bloquant l'accès aux autres
fenêtres du programme) et amodales (indépendantes des autres fenêtres du programme). La classe de base gérant les
boites de dialogues est QDialog. Celle-ci gère le mode modale ou amodale de la fenêtre à partir des méthodes suivantes :

- 103 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

• bool isModal () const : permet de savoir si la boite de dialogue est modale ou pas.
• void setModal (bool modal) : permet de définir si la boite de dialogue est modale ou pas (Par défaut une boite de
dialogue Qt est amodale).
• int exec() : force l'affichage de la boite de dialogue en mode modale (la valeur définie par setModal est ignorée).
• void show() : force l'affichage de la boite de dialogue.
• void hide() : permet de cacher la boite de dialogue.

Création de boites de dialogues modales et amodales


#include <QApplication>
#include <QHBoxLayout>
#include <QPushButton>
#include <QDialog>
#include <QLabel>

class AmodaleDial : public QDialog


{
Q_OBJECT

private :
QLabel * m_Label;

public :
AmodaleDial(QWidget *parent): QDialog(parent) // Contructeur de la fenêtre amodale
{
// Création du label contenu dans la fenêtre
m_Label = new QLabel("Cette fenêtre n'est pas modal", this);
m_Label->resize(100,50);
// Gestion du layout
QHBoxLayout* layout = new QHBoxLayout();
layout->addWidget(m_Label);
setLayout(layout);
}

};

class ModaleDial : public QDialog


{
Q_OBJECT

private :
QLabel* m_Label;

public :
// Contructeur de notre fenêtre
ModaleDial(QWidget *parent): QDialog(parent)
{
// Création du label contenu dans la fenêtre
m_Label = new QLabel ("Cette fenêtre est modale", this);
m_Label->resize(100,50);
QHBoxLayout* layout = new QHBoxLayout();
layout->addWidget(m_Label);
setLayout(layout);
}

};

class Window : public QDialog


{
Q_OBJECT

private :
QPushButton* m_Bouton_ModaleFrame;
QPushButton* m_Bouton_AmodaleFrame;
// Pointeur sur notre fenêtre, amodale
AmodaleDial* m_amodaleDial;

- 104 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Création de boites de dialogues modales et amodales


public :
Window()
{
// Création des différents boutons
m_Bouton_ModaleFrame = new QPushButton("Modale Frame", this);
m_Bouton_AmodaleFrame = new QPushButton("Amodale Frame", this);
// Gestion du layout
QHBoxLayout* layout = new QHBoxLayout();
layout->addWidget(m_Bouton_ModaleFrame);
layout->addWidget(m_Bouton_AmodaleFrame);
setLayout(layout);
// Instanciation de notre fenêtre, amodale
m_amodaleDial = new AmodaleDial(this);
// Connexions des différents signaux et slots pour gérer le clic
connect(this->m_Bouton_ModaleFrame, SIGNAL(clicked(bool)), this, SLOT(clickModale(bool)));
connect(this->m_Bouton_AmodaleFrame, SIGNAL(clicked(bool)), this, SLOT(clickAmodale(bool)));
}

private slots:
void clickModale(bool valid)
{
// Création de notre fenêtre modale
ModaleDial modaleDial(this);
// On rend visible et modale notre fenêtre avec la méthode exec()
modaleDial.exec();
}

void clickAmodale(bool valid)


{
// On rend visible notre fenêtre amodale, par défaut amodale
m_amodaleDial->show();
}

};

#include "main.moc"

int main(int argc, char *argv[])


{
QApplication a(argc, argv);
Window w;
w.show();
return a.exec();
}

Remarque : tous les QWidget, et, par conséquent, leurs classes dérivées, peuvent être modales, en modifiant leur
propriétés windowModality à l'aide de la méthode setWindowModality(). Cependant, il est préférable de gérer ce type
de boite de dialogue à partir d'une QDialog et nom d'un QWidget.

Comment manipuler du texte sélectionné avec QTextCursor ?


Auteurs : Louis du Verdier ,
Les curseurs sont très utilisés dans les classes pouvant les accueillir (comme l'autorisent par défaut QTextEdit,
QTextBrowser et d'autres classes encore).

Pour retrouver la sélection courante qu'à faite l'utilisateur d'un programme, il suffit d'utiliser la fonction selectedText()
de la manière qui suit :

// QString QTextCursor::selectedText () const


widget->textCursor().selectedText();

- 105 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Notes : Cette fonction, retournant un QString, peut parfaitement être vide (empty, en anglais).

Il est de même possible de supprimer la sélection courant à l'aide de removeSelectedText() :

// void QTextCursor::removeSelectedText ()
widget->textCursor().removeSelectedText();

Note : La suppression du texte sélectionné ne se produira que s'il y a lieu d'une sélection.

L'insertion de texte avec l'assistance des curseurs s'effectue avec insertText() qui entre du texte à partir de la position
du curseur.

// void QTextCursor::insertText ( const QString & text, const QTextCharFormat & format )
widget->textCursor().insertText("Chaine de type QString");

Voici un exemple, reprenant ce qui est inscrit ci-dessus, permettant d'effectuer une modification sur un texte sélectionné
sans pour autant modifier plusieurs chaines identiques0

// ...
zoneTexte = new QTextEdit(this);
connect(zoneTexte, SIGNAL(selectionChanged()), this, SLOT(transformer()));
// ...

void XXXXXXXX::transformer()
{
// On garde en mémoire le texte sélectionné
QString selectionTexte(zoneTexte->textCursor().selectedText());
// On supprime celui-ci sans pour autant supprimer les chaines identiques
zoneTexte->textCursor().removeSelectedText();
// Et on effectue l'opération voulue au départ
zoneTexte->textCursor().insertText("<italique>" + selectionTexte + "</italique>");
}

Comment faire un glisser-déposer ?


Auteurs : François Jaffré ,
Pour faire un glisser-déposer avec Qt, c'est très simple, il faut utiliser les méthodes suivantes.

• void QWidget:: setAcceptDrops(bool on) : permet au widget d'accepter tous les glisser-déposer ;
• void QDropEvent:: acceptProposedAction() : permet au widget d'accepter la proposition de glisser-déposer ;
tant qu'on n'a pas accepté la proposition, l'évenement dropEvent() ne se déclenchera pas.

De même, il faut redéfinir les événements suivants.

• void QWidget:: dragEnterEvent (QDragEnterEvent * event) : événement se déclenchant quand on essaie de


faire une glisser-déposer sur le widget.
• void QWidget:: dropEvent (QDropEvent * event) : événement se déclenchant après acceptation du glisser-
déposer.

Glisser-déposer d'images du bureau vers une application


#include <QtGui>
#include <QtGui/QApplication>

- 106 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Glisser-déposer d'images du bureau vers une application


#include <QtGui/QLabel>

class DragImg : public QWidget


{
Q_OBJECT

private:
// Label servant à l'affichage de l'image
QLabel* m_labelImage;

public:
DragImg()
{
// Initialisation des différents contrôles
this->m_labelImage = new QLabel(this);
this->m_labelImage->setFixedSize(320,240);
// Permet au label d'accepter le glisser-déposer
this->m_labelImage->setAcceptDrops(true);
this->m_labelImage->setScaledContents(true);
}

protected :
void dragEnterEvent(QDragEnterEvent *event)
{
// On vérifie que c'est bien un fichier qui est utilisé pour le glisser-déposer
if(event->mimeData()->hasUrls())
{
QFileInfo fileInfo(event->mimeData()->urls().first().toLocalFile());
// On récupère l'extension du fichier
QString suffix = fileInfo.completeSuffix();
suffix = suffix.toLower();
// On verifie que l'extension correspond bien à un type d'image
if( suffix == "png" || suffix == "bmp" || suffix == "jpg")
{
// On accepte le glisser-déposer
event->acceptProposedAction();
}
}

}
void dropEvent(QDropEvent *event)
{
// On récupère tout les fichiers sélectionnés par l'utilisateur pour le glisser-déposer
QList<QUrl> urls = event->mimeData()->urls();
if (urls.isEmpty())
return;
// On récupère le chemin de la première image sélectionnée
QString fileName = urls.first().toLocalFile();
if (fileName.isEmpty())
return;
// On affiche l'image dans le label
this->m_labelImage->setPixmap(QPixmap(fileName));
}

};

#include "main.moc"

int main(int argc, char *argv[])


{
QApplication a(argc, argv);
DragImg w;
w.show();
return a.exec();

- 107 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Glisser-déposer d'images du bureau vers une application


}

Comment connaître la position et repositionner la souris sur l'écran ?


Auteurs : Yan Verdavaine ,
Pour cela, la classe QCursor fournit deux fonctions statiques :
• QPoint QCursor:: pos () : retourne la position de la souris ;
• void QCursor:: setPos ( const QPoint & ) : prend en paramètre la nouvelle position de la souris.

#include <QtGui>

class widget : public QWidget


{
Q_OBJECT
QTextBrowser *m_tb;
QTimer m_timer;

public:
widget()
{
QVBoxLayout * l = new QVBoxLayout(this);
m_tb = new QTextBrowser;
l->addWidget(m_tb);

// Repositionnement aléatoire de la souris


QPushButton * b = new QPushButton("repositionner la souris");
connect (b,SIGNAL(clicked()),this,SLOT(PositionAleatoire()));
l->addWidget(b);

connect(&m_timer,SIGNAL(timeout()),this,SLOT(AfficherPosition()));
// Affichage de la position tous les 0.5 seconde
m_timer.start(500);
}

public slots:
void AfficherPosition()
{
// Position de la souris
QPoint p = QCursor::pos();
m_tb->append(QString("curseur (%1,%2)").arg(p.x()).arg(p.y()));
}

void PositionAleatoire()
{
// Repositionnement de la souris
QCursor::setPos
(
QApplication::desktop()->width() * (qrand() / (double)RAND_MAX),
QApplication::desktop()->height() * (qrand() / (double)RAND_MAX)
);
}
};

#include "main.moc"
int main (int argc, char * argv[])
{
QApplication app(argc,argv);
qsrand (QTime::currentTime().msec());
widget w ;
w.show();
return app.exec();

- 108 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Comment récupérer la résolution d'écran de l'utilisateur ?


Auteurs : Louis du Verdier ,
Grâce à la classe QDesktopWidget, il est possible de récupérer la résolution d'écran de l'utilisateur.

QApplication::desktop(), une fonction permettant d'obtenir l'instance de QDesktopWidget correspondant à ce qu'on


appelle le widget de bureau, a été utilisé dans l'exemple ci-dessous mais aurait tout autant pu être remplacée par une
instanciation explicite d'un objet QDesktopWidget.

int largeur = QApplication::desktop()->width();


int hauteur = QApplication::desktop()->height();

Comme le dit la documentation, les fonctions width() et height() sont utilisables ici, car QDesktopWidget hérite de
QWidget.

Il aurait aussi été possible de passer par la fonction screenGeometry(), appartenant aussi à
QDesktopWidget, qui retourne un QRect pour récupérer la résolution d'écran, ce qui aurait
pour avantage de pouvoir retourner la résolution de chaque écran. Le fait que cette fonction
retourne un QRect permettrait, dans le cas où l'on serait passé par la méthode avec les
fonctions width() et height(), de retourner les valeurs recherchées.

Comment recupérer l'identifiant système d'une fenêtre ou d'un widget ?


Auteurs : François Jaffré ,
Il peut parfois être nécessaire de vouloir recupérer l'identifiant système d'une fenêtre ou d'un widget, notamment si l'on
souhaite utiliser Qt avec les API spécifiques à chaque système. Pour cela, Qt fournit la méthode WId QWidget::winId
() const.

Exemple d'utilisation pour Windows


#include <windows.h>
//...
HWND hwnd = monWidget->winId();

Exemple d'utilisation pour Linux


#include <X11/X.h>
//...
Window window = reinterpret_cast<Window>(monWidget->winId());

Exemple d'utilisation pour Mac OS X (Carbon - 32 bits)


#include <Carbon/Carbon.h>
//...
HIViewRef view = reinterpret_cast<HIViewRef>(monWidget->winId());

Exemple d'utilisation pour Mac OS X (Cocoa - 64 bits)


#include <Cocoa/Cocoa.h>
//...

- 109 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Exemple d'utilisation pour Mac OS X (Cocoa - 64 bits)


NSView *view = reinterpret_cast<NSView*>(monWidget->winId());

Comment afficher un widget dans une zone MDI ?


Auteurs : Yan Verdavaine ,
La zone MDI est une sorte d'émulation d'un bureau qui va permettre d'afficher un ou plusieurs widgets avec une
décoration. Lors de l'ajout d'une widget, son affichage n'est pas automatique.

On peut constater deux cas :


• L'ajout après construction : si les widget sont ajoutés juste après la construction du QMDIArea, ils seront
automatiquement affichés.
• L'ajout dynamique : une widget ajoutée à un QMDIArea possède les même propriétés qu'un widget sans parent,
et doit donc être explicitement affiché par show() ou équivalent.

#include <QtGui>

class MainWindow : public QMainWindow


{
Q_OBJECT
int id;
QMdiArea * m_area;
public :
MainWindow()
:id(0)
{
m_area = new QMdiArea;
setCentralWidget(m_area);
menuBar()->addAction("ajouter windows",this,SLOT(newWindows()));
//création de 4 fenêtres qui seront affichées en même temps que MainWindow
for (int i =0; i< 4;++i)
{
QMdiSubWindow * tmp = m_area->addSubWindow(new QTextEdit);
tmp->setWindowTitle(QString("fenetre %1").arg(id++));
}
}

public slots:
void newWindows()
{
// création d'une nouvelle fenêtre
QMdiSubWindow * tmp = m_area->addSubWindow(new QPushButton);
tmp->setWindowTitle(QString("fenetre %1").arg(id++));
//affichage de la fenêtre
tmp->show();
}
};

#include "main.moc"

int main(int argc, char *argv[])


{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}

- 110 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sommaire > QtGui > Animations


Comment afficher un gif animé ?
Auteurs : Yan Verdavaine ,
Comme un GIF animé est non statique, on ne peut pas afficher l'animation avec une QImage ou une QPixmap. Pour
cela, Qt fournit une classe réservée aux vidéos : QMovie.

La méthode la plus simple est de créer un QMovie avec le GIF et de l'associer à un label.

#include <QtGui>

int main(int argc, char* argv[])


{
QApplication app(argc, argv);
QLabel w;

// On crée une vidéo. Ici, c'est un GIF


QMovie movie("c:/Mickey-11.gif");
// On l'associe à un label
w.setMovie (&movie);
// On lance la vidéo
movie.start ();

w.show();
return app.exec();
}

Il faut tout de même préciser que la compilation du plug-in GIF est nécessaire pour que ce code fonctionne correctement.

Comment avoir une icône animée ?


Auteurs : Yan Verdavaine ,
Il peut être intéressant d'avoir des icônes qui évoluent dans le temps. Par exemple, une icône dans la barre des tâches
qui donne l'avancement d'un traitement. Pour animer une QIcon, il suffit de remplacer l'image à utiliser à l'instant t.

Voici trois méthodes simples.

1- Un fichier image animé (gif, mng...) et QMovie


• QMovie émet un signal à chaque changement d'image.
• Il suffit de connecter un slot qui va récupérer l'image courante de QMovie
• L'icône peut être animée par la lecture de l'animation.
• Il est possible de contrôler l'avancement de l'animation avec la méthode jumpToFrame().

Le bouton permet de charger une image animée


#include <QtGui>

class MyWindow : public QWidget


{
Q_OBJECT
// lecteur d'image animee
QMovie m_movie;
//objets qui utilisent une icône
QPushButton *m_but;
QSystemTrayIcon m_sysTray;

- 111 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Le bouton permet de charger une image animée


public :
MyWindow( )
{
// layout et le bouton seront re-parentés
// par le setLayout
QLayout * l = new QVBoxLayout;
{
m_but = new QPushButton;
l->addWidget(m_but);
}
setLayout(l);
// connecte l'événement updated pour changer d'image dans les icônes
connect(&m_movie, SIGNAL(updated ( const QRect & )),this,SLOT(nouvelleIcone()));
// bouton : permet de prendre une autre image animée
connect(m_but, SIGNAL(clicked( )),this,SLOT(nouvelleImageAnimee()));

// ajout dans l'event loop


QTimer::singleShot(0,this,SLOT(chargerImageAnimee()));
}
private slots:
// sélection d'une image animée et lecture par le QMovie
void chargerImageAnimee()
{
QString s =QFileDialog::getOpenFileName(this,"choisir une image animee",QString(),"*.gif
*.mng");
if (!s.isEmpty())
{
m_movie.stop();
m_movie.setFileName(s);
m_movie.start();
}

// modifie l'icône pour le bouton, le systray et le titre de la fenêtre


void nouvelleIcone()
{
QIcon icon(m_movie.currentPixmap());
//modifie l'icone du boutton
m_but->setIcon(icon);
//modifie l'icone du systray
m_sysTray.setIcon(icon);
m_sysTray.show();
//modifie l'icone de la fenetre
setWindowIcon(icon);
}

};
// astuce pour ne pas avoir plusieurs fichiers
#include "main.moc"

int main(int argc, char* argv[])


{
QApplication app(argc, argv);
MyWindow w;
w.show();
return app.exec();
}

2- Une liste d'image


• À chaque événement de changement d'image, on choisit l'image dans la liste.
• Un timer permet de faire évoluer l'animation de manière constante.

Charge les images d'un répertoire dans une liste

- 112 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Charge les images d'un répertoire dans une liste


#include <QtGui>

class MyWindow : public QWidget


{
Q_OBJECT
// liste d'images
QList<QPixmap> m_lImages;
// objets qui utilisent une icône
QPushButton *m_but;
QSystemTrayIcon m_sysTray;
public :
MyWindow( )
{
// layout et le bouton seront re-parentés
// par le setLayout
QLayout * l = new QVBoxLayout;
{
// slider qui permet d'émuler l'avancement
QSlider * slider = new QSlider(Qt::Horizontal);
slider->setRange ( 0,100 );
connect (slider,SIGNAL(valueChanged ( int )),this,SLOT (nouvelleIcone(int)));
l->addWidget(slider);

m_but = new QPushButton;


l->addWidget(m_but);
}
setLayout(l);

// bouton : permet de prendre une autre image animée


connect(m_but, SIGNAL(clicked( )),this,SLOT(chargerRepertoire()));

// ajout dans l'event loop


QTimer::singleShot(0,this,SLOT(chargerImageAnimee()));
}
private slots:
//charger les image d'un repertoire dans une liste
void chargerRepertoire()
{
QString s =QFileDialog::getExistingDirectory(this,"choisir une image animee",QString());
m_lImages.clear();
QDir d(s);
QStringList filters;
filters << "*.jpg" << "*.png" << "*.gif";
// pour chaque fichier image du répertoire
// on lie l'image et on l'ajoute dans la liste
foreach(QString file,d.entryList (filters,QDir::Files))
{
QPixmap tmp(d.absolutePath()+"/"+file);
if ( !tmp.isNull ())
m_lImages<<tmp;
}
}

// modifie l'icône pour le bouton, le systray et le titre de la fenêtre


void nouvelleIcone(int pourcent)
{
if (m_lImages.size() == 0)
return;

// on choisit l'image
QIcon icon(m_lImages[pourcent%m_lImages.size()]);
// modifie l'icône du bouton
m_but->setIcon(icon);
// modifie l'icône du systray
m_sysTray.setIcon(icon);
m_sysTray.show();
// modifie l'icône de la fenêtre

- 113 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Charge les images d'un répertoire dans une liste


setWindowIcon(icon);
}

};
//astuce pour ne pas avoir plusieurs fichiers
#include "main.moc"

int main(int argc, char* argv[])


{
QApplication app(argc, argv);
MyWindow w;
w.show();
return app.exec();
}

3- Un QPainter
• À chaque événement qui demande un changement de l'icône, on crée une nouvelle image avec un QPainter.
• La plus compliquée à mettre en place mais la plus puissante.
• La création d'une nouvelle icône peut mettre du temps.

Compose une image à partir de deux images


#include <QtGui>

class myWindows : public QWidget


{
Q_OBJECT
public :
myWindows()
{
QGridLayout * l = new QGridLayout;
{
// slider qui permet d'émuler l'avancement
QSlider * slider = new QSlider(Qt::Horizontal);
slider->setRange ( 0,100 );
connect (slider,SIGNAL(valueChanged ( int )),this,SLOT (noucelleIcone(int)));
l->addWidget(slider,0,0,1,3);

// bouton pour charger la première image


QPushButton * b = new QPushButton("charger Pix1");
connect(b,SIGNAL(clicked()),this,SLOT(OpenPix1()));
// label qui affiche la première image
m_Apix1 =new QLabel;
l->addWidget(b,1,0);
l->addWidget(m_Apix1,2,0);

// bouton qui affiche une l'icôn calculée


m_AresultIcone = new QPushButton;
// label qui affiche l'image calculée
m_Aresult =new QLabel;
l->addWidget(m_AresultIcone,1,1);
l->addWidget(m_Aresult,2,1);

// bouton pour charger la deuxième image


QPushButton * b = new QPushButton("charger Pix2");
connect(b,SIGNAL(clicked()),this,SLOT(OpenPix2()));
// label qui affiche la deuxième image
m_Apix2 =new QLabel;
l->addWidget(b,1,2);
l->addWidget(m_Apix2,2,2);
}
setLayout(l);

m_trayIcon.show();

- 114 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Compose une image à partir de deux images


}

private slots :

void noucelleIcone(int percent)


{

// pixmap avec un fond transparent


QPixmap resultImage(200,200);
resultImage.fill(Qt::transparent);
{
QPainter painter(&resultImage);

// précalcule les pourcentages de la hauteur


float percent_1 = (100.- percent)/100.;
float percent_2 = percent/100.;

// haut de l'image
QRect target(0, 0, resultImage.width(), percent_1*resultImage.height());
QRect source(0, 0, m_pix1.width(), percent_1*m_pix1.height());
painter.drawPixmap(target, m_pix1, source);

// bas de l'image
QRect target2(0, percent_1*resultImage.height(), resultImage.width(),
percent_2*resultImage.height());
QRect source2(0, percent_1*m_pix2.height(), m_pix2.width(), percent_2*m_pix2.height());
painter.drawPixmap(target2, m_pix2, source2);

// pourcentage
painter.setPen(QPen(Qt::black));
painter.setFont(QFont("TAHOMA",80,20));
painter.drawText(10,resultImage.height()/2,QString::number(percent));
}
QIcon iconeCourante(resultImage);
//affichage dans un label
m_Aresult->setPixmap(resultImage);
//affichage sous forme d'icone dans un bouton
m_AresultIcone->setIcon(iconeCourante);
//icone de la fenetre
setWindowIcon (iconeCourante);
//icone du systray
m_trayIcon.setIcon(iconeCourante);

}
void OpenPix1()
{
static QString s;
s =QFileDialog::getOpenFileName
(
this,
"image 1",
s,
"images (*.jpg *.png *.bmp *.gif)\n *.*"
);
if (! s.isEmpty())
{
QPixmap tmp(s);
m_pix1 = tmp.scaled(200,200,Qt::KeepAspectRatio);
m_Apix1->setPixmap(m_pix1);
}
}
void OpenPix2()
{
static QString s;
s =QFileDialog::getOpenFileName
(

- 115 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Compose une image à partir de deux images


this,
"image 2",
s,
"images (*.jpg *.png *.bmp *.gif)\n *.*"
);
if (! s.isEmpty())
{
QPixmap tmp(s);
m_pix2 = tmp.scaled(200,200,Qt::KeepAspectRatio);
m_Apix2->setPixmap(m_pix2);
}
}
private :
QPixmap m_pix1;
QPixmap m_pix2;

QLabel * m_Apix1;
QLabel * m_Apix2;

QSystemTrayIcon m_trayIcon;
QPushButton * m_AresultIcone;
QLabel * m_Aresult;
};

#include "main.moc"

int main(int argc, char *argv[])


{

QApplication app(argc,argv);
myWindows w;
w.show();

return app.exec();
}

- 116 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sommaire > QtGui > Graphics View


Qu'est-ce que Graphics View ?
Auteurs : Benjamin Poulain ,
Graphics View est une infrastructure qui permet de dessiner des scènes 2D complexes.

Graphics View permet de :


• Dessiner des éléments en 2D,
• Faire interagir l'utilisateur avec ces éléments,
• Appliquer des transformations avancées sur les éléments,
• Animer les éléments.

Voici un exemple minimaliste pour montrer quelques possibilités de Graphics View.

Insérer une boîte de dialogue dans la scène, et la déformer


#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsProxyWidget>
#include <QGraphicsView>
#include <QFileDialog>

int main(int argc, char **argv)


{
QApplication app(argc, argv);
QGraphicsScene scene;
QGraphicsView view(&scene);

QFileDialog fileDialog;
QGraphicsProxyWidget *item = scene.addWidget(&fileDialog);
item->rotate(-15);
item->shear(-0.5, 0);

view.resize(800, 600);
view.show();
return app.exec();
}

Comment accélérer Graphics View ?


Auteurs : Benjamin Poulain ,
Si vous avez un problème de vitesse avec Graphics View, commencez par vérifier que le problème ne se situe pas dans un
de vos items. Graphics View est extrêmement performant, il n'est pas inhabituel d'y dessiner plusieurs milliers d'éléments
(essayez la démo chip par exemple). Les problèmes de vitesse sont généralement dus à un graphics item qui se dessine
trop lentement, ou à des rafraîchissements abusifs.

Si le problème ne vient pas de là, vous pouvez utiliser un back-end plus performant pour dessiner. Dessiner avec les back-
end de la plateforme est assez lent, Qt contourne le problème en dessinant sur un format interne optimisé. Cela peut être
configuré en ajoutant -graphicssystem raster ou -graphicssystem opengl dans les paramètres de la ligne de commande
de l'application. Notez que l'option raster ne change rien pour Windows, car c'est déjà le back-end par défaut.

view.setViewport(new QGLWidget);

- 117 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Si cela n'est toujours pas suffisant, il vous faut optimiser précisément votre vue à l'aide des options de QGraphicsView.
Une première option à considérer est renderHints. Cette option permet de configurer les paramètres du QPainter utilisé
pour dessiner la scène. Si vous utilisez l'anti-aliasing par exemple, cela ralentit fortement le dessin des items.

view.setRenderHint(QPainter::Antialiasing, false);
view.setRenderHint(QPainter::TextAntialiasing, false);

Un autre paramètre utile est optimizationFlags. Cette propriété permet de changer les paramètres de bas niveau du
dessin de la scène. Par exemple, concevoir les items pour pouvoir utiliserQGraphicsView::DontSavePainterState est
important si les items sont très nombreux. À la différence des autres options, les paramètres de optimizationFlags
impliquent des effets de bords sur le rendu de la scène. Ne changez ce paramètre que si vos items sont conçus en
conséquence.

Finalement, il existe le paramètre cacheMode pour accélérer le rendu du fond de la vue. Le cacheMode permet de
demander à la vue de créer un cache pour l'image de fond. Cette option n'est utile que si le fond est long à dessiner, par
exemple s'il s'agit d'une image, d'un dégradé ou si la transparence est utilisée.

view.setCacheMode(QGraphicsView::CacheBackground);

- 118 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sommaire > QtGui > Model View


Qu'est ce que Model View ?
Auteurs : Benjamin Poulain ,
Model View est l'infrastructure de Qt qui permet de gérer les vues arborescentes, les listes et les tables. Il se base sur
un pattern Model-View-Delegate.

Le modèle est une interface vers les données, ce qui permet d'abstraire la façon dont celle-ci sont représentées (mémoire,
base de données, système de fichier, etc.).

La vue est la représentation visuelle des données sur l'écran. Qt fournit trois types de représentations : liste (QListView),
arbre (QTreeView) et tableaux (QTableView).

Le délégué permet de faire le lien entre la vue et le modèle. Le délégué se charge de dessiner les éléments du modèle
dans la vue, et de gérer l'édition de ces éléments.

Par rapport à Modèle-Vue-Contrôleur, le délégué est une sorte de super-contrôleur. Il génère un éditeur à la demande
de la vue, et se charge de faire parvenir les informations au modèle, c'est son rôle de contrôleur. En plus de cela, le
délégué se charge de dessiner les éléments du modèle, ce qui permet de pouvoir complètement personnaliser la vue.

Exemple d'utilisation de Model View en utilisant le système de fichier comme modèle


#include <QApplication>
#include <QFileSystemModel>
#include <QTreeView>
#include <QListView>
#include <QTableView>

int main(int argc, char **argv)


{
QApplication app(argc, argv);

QFileSystemModel model; // le modèle est ici le système de fichier


model.setRootPath(QDir::rootPath());

QTreeView treeView;
treeView.setModel(&model);
QListView listView;
listView.setModel(&model);
QTableView tableView;
tableView.setModel(&model);

// partageons la selection pour plus de cohérence


QItemSelectionModel *selection = treeView.selectionModel();
listView.setSelectionModel(selection);
tableView.setSelectionModel(selection);

// changeons la racine en fonction de la selection


// (car les tables et listes en sont pas fait pour naviguer, on pourra toujours naviguer avec
l'arbre)
QObject::connect(selection, SIGNAL(currentChanged(const QModelIndex, const QModelIndex)),
&listView,
SLOT(setRootIndex(const QModelIndex)));
QObject::connect(selection, SIGNAL(currentChanged(const QModelIndex, const QModelIndex)),
&tableView,
SLOT(setRootIndex(const QModelIndex)));

treeView.show();
listView.show();
tableView.show();

- 119 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Exemple d'utilisation de Model View en utilisant le système de fichier comme modèle


return app.exec();
}

Comment trier un QTreeWidget ?


Auteurs : Yan Verdavaine ,
Les QTreeWidget trient leurs items grâce à l'opérateur < des QTreeWidgetItem. Par défaut, cet opérateur compare
deux QString. Malheureusement, ceci ne correspond pas toujours à ce que l'on souhaite.

Pour y remédier, il suffit de créer sa propre classe d'item qui hérite de QTreeWidgetItem et qui redéfinit cet opérateur.
Tout fonctionnera grâce au polymorphisme !

Exemple : différence entre le tri lexical de QTreeWidgetItem et le tri numérique implémenté par notre classe item

Trier un QTreeWidget
#include <QtGui>
#include <cstdlib> // srand(), rand() et RAND_MAX
#include <ctime> // time()

class MyQTreeWidgetItem :public QTreeWidgetItem


{
public :
// Constructeur de MyQTreeWidgetItem
MyQTreeWidgetItem ( QTreeWidgetItem * parent, int type = Type ):QTreeWidgetItem(parent,type){};
MyQTreeWidgetItem ( QTreeWidget * parent, int type = Type ):QTreeWidgetItem(parent,type){};

// Réimplemente le test
bool operator< ( const QTreeWidgetItem & other ) const
{
// On récupère la colonne utilisée pour le test
const QTreeWidget * pTree =treeWidget ();
// Si aucun TreeWidget n'est associé, on utilise la colonne 0
int colonne = pTree ? pTree->sortColumn() : 0;

// On récupère les données sous forme de variant situé dans la colone


QVariant q1= data ( colonne , 0 );
QVariant q2= other.data ( colonne , 0 );
// On vérifie que les deux variants sont de même type
if (q1.type() == q2.type())
{
// Si ce sont des int
if (q1.type()==QVariant::Int) return q1.toInt()<q2.toInt();
// Si ce sont des double
if (q1.type()==QVariant::Double) return q1.toDouble()<q2.toDouble();
}
// Sinon on appele le comparateur de la class mere "QTreeWidgetItem"
return QTreeWidgetItem::operator<(other);
}
};

int main(int argc, char* argv[])


{
srand(time(NULL));
QApplication app(argc, argv);

QTreeWidget tree;
// On remplit l'en-tête
QStringList entete;
entete << "int" << "double" ;

- 120 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Trier un QTreeWidget
tree.setHeaderItem(new QTreeWidgetItem((QTreeWidgetItem*)0,entete));
tree.setSortingEnabled(true);

// On crée une première branche avec des QTreeWidgetItem


// Les items seront triés de manière lexicale
QTreeWidgetItem *parentitem = new QTreeWidgetItem(&tree);
parentitem->setText(0,"QTreeWidgetItem");
for (int i=0;i<20;++i)
{
QTreeWidgetItem*item = new QTreeWidgetItem(parentitem);
item ->setData (0, 0, QVariant(i));
item ->setData (1, 0, QVariant(rand()/(1.+RAND_MAX)*i));
}

// On crée une deuxième branche avec notre nouvelle classe


// Les items seront triés de manière numérique
parentitem = new MyQTreeWidgetItem(&tree);
parentitem->setText(0,"MyQTreeWidgetItem ");
for (int i=0;i<20;++i)
{
MyQTreeWidgetItem *item = new MyQTreeWidgetItem(parentitem);
item ->setData (0, 0, QVariant(i));
item ->setData (1, 0, QVariant(rand()/(1.+RAND_MAX)*i));
}

tree.resize(400, 650);
tree.expandAll();
tree.show();
return app.exec();
}

Comment trier un QListWidget ?


Auteurs : Yan Verdavaine ,
Les QListWidget trient leurs items avec l'opérateur < des QListWidgetItem. Par défaut, cet opérateur compare deux
QString. Malheureusement, ceci ne correspond pas toujours à ce que l'on souhaite. Pour y remédier, il suffit de créer
sa propre classe d'item qui hérite de QListWidgetItem et qui redéfinit cet opérateur. Tout fonctionnera simplement
grâce au polymorphisme.

Différence entre le tri par ordre croissant numérique implémenté par notre classe item (vue de gauche) et le tri par
ordre croissant lexical des QListWidgetItem (vue de droite).

Trier un QListWidget
#include <QtGui>

class MyQListWidgetItem :public QListWidgetItem


{
public :
// Constructeur de MyQListWidgetItem.
MyQListWidgetItem ( QListWidget * parent, int type = Type ):QListWidgetItem(parent,type){};

// Réimplémente le test
bool operator< ( const QListWidgetItem & other ) const
{
//On récupère les données sous forme de variant
QVariant q1= data ( 0 );
QVariant q2= other.data ( 0 );
//On verifie que les deux variants sont de même type
if (q1.type() ==q2.type())

- 121 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Trier un QListWidget
{
// Si ce sont des int
if (q1.type()==QVariant::Int) return q1.toInt()<q2.toInt();
// Si ce sont des double
if (q1.type()==QVariant::Double) return q1.toDouble()<q2.toDouble();
}
// Sinon on appelle le comparateur de la classe mère "QListWidgetItem"
return QListWidgetItem::operator<(other);
}

};

int main(int argc, char* argv[])


{
QApplication app(argc, argv);

// Viewer de gauche
QListWidget * pList1 = new QListWidget;
// On active le tri. Par défaut, tri par ordre croissant
pList1->setSortingEnabled(true);
// On utilise nos items. Tri par ordre numérique
for (int i=0;i<20;++i)
{
QListWidgetItem*item = new MyQListWidgetItem(pList1);
item ->setData ( 0, QVariant(i));
}

// Viewer de droite
QListWidget * pList2 = new QListWidget;
// On active le tri. Par defaut, tri par ordre croissant
pList2->setSortingEnabled(true);
// On utilise les QListWidgetItem. Tri ordre lexical
for (int i=0;i<20;++i)
{
QListWidgetItem*item = new QListWidgetItem(pList2);
item ->setData ( 0, QVariant(i));
}

QWidget w;
QHBoxLayout hl(&w);
hl.addWidget(pList1);
hl.addWidget(pList2);
w.resize(400, 400);
w.show();
return app.exec();
}

Comment effacer le contenu d'un QTableWidget ?


Auteurs : François Jaffré ,
Pour effacer le contenu d'un QTableWidget c'est très simple, il faut tout d'abord effacer les QTableWidgetItem qu'il
contient puis effacer toutes les lignes du tableau.

//On efface les QTableWidgetItem contenu dans le tableau


tableWidget->clear();
//On efface toutes les lignes du tableau
tableWidget->setRowCount(0);

- 122 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sommaire > QtGui > Assistants


Quelles sont les techniques pour créer un assistant ?
Auteurs : Thibaut Cuvelier ,
Déjà, intéressons-nous à cette question : qu'est-ce qu'un assistant ?

Il s'agit d'une suite de fenêtres, contenant des formulaires, dont les données sont gardées, et peuvent servir à choisir
la fenêtre suivante.

Pour garder les données, vous pouvez créer un nouveau type d'objet, avec uniquement des accesseurs et des variables
membres privées. Quand l'utilisateur validera un formulaire, les setters seront utilisés pour écrire les données du
formulaire. Quand vous devrez personnaliser un formulaire, vous utiliserez les getters pour récupérer les données qui
vous intéressent.

Pour passer d'une fenêtre à l'autre, deux solutions sont possibles.

1 Vous créez une nouvelle fenêtre et vous détruisez l'ancienne ;


2 Vous cachez les éléments de la fenêtre et vous affichez ceux qui sont utiles à votre nouveau formulaire.

Il existe quelques différences pour l'utilisateur entre ces deux solutions.

• Quand vous utilisez la première, lors du changement de fenêtres, elle va disparaître et une nouvelle apparaîtra,
à la fin de la barre des tâches.
• Si vous détruisez vos fenêtres ou vous widgets, cela prendra du temps, mais aussi, et surtout, cela évitera de
prendre trop de mémoire ;
• Au niveau implémentation, les différences peuvent être énormes en termes de longueur.

Premièrement, vous créerez, probablement, un objet qui va s'occuper de la gestion des fenêtres et des widgets. Celui-ci
disposera alors de slots qui vont vous permettre de passer d'une fenêtre à l'autre. Ces slots seront connectés aux signaux
des widgets "Suivant" et "Précédent" des fenêtres.
Si vous utilisez la première solution, les slots ne feront que détruire une fenêtre, et en construire une autre.
Si vous utilisez la seconde, les slots devront cacher tous les anciens widgets, construire et afficher tous les nouveaux.

Deuxièmement, dans cet objet de gestion de l'assistant, vous stockerez des pointeurs vers vos fenêtres (première
solution), ou vers tous les widgets qui vont être utilisés (deuxième solution).

Qt gère lui-même tout cela de manière interne, grâce à la famille de classes QWizard.

Comment créer un assistant ?


Auteurs : Thibaut Cuvelier ,
La classe QWizard permet de créer des assistants. Elle est apparue avec Qt3, mais n'a été réintégrée à Qt4 que depuis
la version 4.3.

Cette classe ne contient elle-même que la logique de l'assistant : toutes les pages sont des QWizardPage, que vous liez
avec un ou plusieurs QWizard.

Voici une utilisation très basique de cette classe, avec trois pages qui se suivent dans l'ordre d'enregistrement auprès
du QWizard.

- 123 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Notez que nous aurions pu créer des classes héritant de QWizardPage, et en proposer une instance à QWizard, au lieu
de créer des fonctions qui s'occupent de les instancier. Cette dernière technique permet de simplifier le code ; tandis
que l'héritage permet de personnaliser encore plus les pages.

QWizardPage *createIntroPage()
{
QWizardPage *page = new QWizardPage;
page->setTitle("Introduction");

QLabel *label = new QLabel("Cet assistant va vous aider à enregistrer votre copie du
logiciel.");
label->setWordWrap(true);

QVBoxLayout *layout = new QVBoxLayout;


layout->addWidget(label);
page->setLayout(layout);

return page;
}

// Ces deux fonctions ont un contenu analogue à celui de createIntroPage()


QWizardPage *createRegistrationPage();
QWizardPage *createConclusionPage();

int main(int argc, char *argv[])


{
QApplication app(argc, argv);

QWizard wizard;
wizard.addPage(createIntroPage());
wizard.addPage(createRegistrationPage());
wizard.addPage(createConclusionPage());

wizard.setWindowTitle("Assistant simple");
wizard.show();

return app.exec();
}

Comment créer une page d'un assistant ?


Auteurs : Thibaut Cuvelier ,
La classe QWizardPage représente une page d'un assistant QWizard.

Une page est constituée, comme toute fenêtre, de widgets. Ces widgets peuvent être rassemblés en layouts : par exemple,
des boîtes (QBoxLayout : QHBoxLayout, QVBoxLayout), des formulaires ( QFormLayout), des grilles (QGridLayout)...

Vous devez associer tous les widgets de la page en layouts, que vous pouvez ajouter simplement grâce à la méthode
setLayout().

Cette classe hérite de QWidget : vous pouvez donc utiliser l'ensemble des méthodes de cette classe pour personnaliser
votre page.

Si vous devez personnaliser encore plus votre page, vous pouvez hériter de QWizardPage, et redéfinir ses méthodes
pour obtenir le résultat souhaité.

QWizardPage *page = new QWizardPage;


page->setTitle("Introduction");

- 124 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

QLabel *label = new QLabel("Cet assistant va vous aider à enregistrer votre copie du logiciel.");

QVBoxLayout *layout = new QVBoxLayout;


layout->addWidget(label);
page->setLayout(layout);

Comment traduire un assistant ?


Auteurs : Thibaut Cuvelier ,
Vous pouvez traduire des QWizard comme n'importe quel widget.

Pour cela, il vous faut installer un QTranslator dans votre QApplication, et lui préciser le fichier dans lequel se situent
les traductions. Cette méthode est applicable pour toutes les applications.

N'oubliez pas de protéger chaque chaîne à traduire avec tr() !

QApplication app(argc, argv);

QString translatorFileName = QLatin1String("qt_");


translatorFileName += QLocale::system().name();
QTranslator *translator = new QTranslator(&app);
if (translator->load(translatorFileName, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
app.installTranslator(translator);

QWizard wizard;
wizard.addPage(new QWizardPage());

wizard.setWindowTitle(tr("Titre"));
wizard.show();

return app.exec();

Comment choisir le style d'un assistant ?


Auteurs : Thibaut Cuvelier ,
Les assistants QWizard sont des widgets comme tous les widgets de Qt, ils peuvent se plier aux exigences d'un style.

La méthode setWizardStyle() vous permettra de choisir entre ces quatre styles, s'ils ont été compilés en même temps
que Qt :

• ClassicStyle (comme Win9X) ;


• ModernStyle (comme Windows XP) ;
• AeroStyle (comme Windows Vista et Seven, quand Aero est activé ; sinon, Qt bascule vers ModernStyle) ;
• MacStyle (comme MacOS X).

Ces styles sont définis dans une énumération, WizardStyle, que voici.

- 125 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

WizardStyle { ClassicStyle, ModernStyle, MacStyle, AeroStyle }

Comment personnaliser un assistant ?


Auteurs : Thibaut Cuvelier ,
Avant de se lancer dans la personnalisation d'un assistant, il faut déjà savoir à quoi correspond chaque item.

MacStyle

- 126 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

ModernStyle (modèle pour les autres styles)

title se modifie avec la méthode setTitle().

wizard()->setTitle( QString() );

subTitle se modifie avec la méthode setSubTitle().

wizard()->setSubTitle( QString() );

Vous pouvez aussi décider de ne pas afficher le sous-titre.

wizard()->setOption(QWizard::IgnoreSubTitles, true);

- 127 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Les autres éléments modifiables sont des images. Ces images peuvent être finement modifiés, c'est-à-dire que cette
méthode est aussi disponible sur les QWizardPage. La méthode à utiliser est setPixmap().

Elle prend deux paramètres : le premier, l'image à modifier ; le second, le QPixmap qui va être utilisé.

WizardPixmap { WatermarkPixmap, LogoPixmap, BannerPixmap, BackgroundPixmap }

wizard()->setPixmap (QWizard::WatermarkPixmap, QPixmap() );

Comment modifier un bouton ou insérer un bouton personnalisé dans un assistant ?


Auteurs : Thibaut Cuvelier ,
La méthode setButton() permet de définir un bouton pour un rôle précis. Le bouton doit être un QAbstractButton ou
un de ses dérivés ; le rôle est défini dans l'énumération WizardButton, que voici.

WizardButton
{
BackButton,
NextButton,
CommitButton,
FinishButton,
CancelButton,
HelpButton,
CustomButton1,
CustomButton2,
CustomButton3,
Stretch
}

Vous pouvez personnaliser tous les boutons, et même ajouter trois bouton entièrement personnalisés.

Pour modifier un bouton, vous pouvez utiliser la méthode setButton(). Pour modifier son texte, setButtonText(). Pour
modifier son layout, setButtonLayout().

Chacune de ces fonctions prend, en premier paramètre, le rôle du bouton que vous voulez modifier.

wizard()->setButton(QWizard::CustomButton1, new QButton("Bouton");

Quand vous spécifiez un bouton personnalisé, il n'est affiché que si vous demandez à Qt de l'afficher. Pour cela, vous
devez utiliser la méthode setOption().

wizard()->setOption(QWizard::HaveCustomButton1, true);

Le signal customButtonClicked() est émis lorsqu'un bouton personnalisé est enfoncé. Son paramètre est le rôle du
bouton enfoncé

- 128 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sommaire > QtGui > Style


Fenêtre et transparence ?
Auteurs : Yan Verdavaine ,
Qt permet diverses actions pour jouer avec la transparence d'une fenêtre :

• Masque : à partir d'une image binaire (QBitmap), il est possible de spécifier quelle partie est visible ou non
sur la fenêtre. Cette méthode s'applique à tous les éléments d'une fenêtre top-level. Par exemple la partie d'un
bouton qui se trouve dans une zone transparente ne sera pas dessinée. Pour utiliser un masque il faut créer une
QBitmap et utiliser la fonction setMask (définie par QWidget) sur le widget parent. Sur certains OS comme
Windows XP, il est obligatoire d'enlever la décoration avec le flag Qt::FramelessWindowHint.
• Opacité : permet de rendre translucide toute une fenêtre. Pour cela il faut utiliser la méthode
setWindowOpacity() (définie par QWidget) sur le widget parent. Cette méthode prend en paramètre une valeur
réelle entre 0 (transparent) et 1 (opaque).
• Transparence : depuis la version 4.5, il est possible de spécifier que le background de la widget parente soit
transparent. Il est ainsi possible de jouer avec la transparence des différents éléments et QPainter pour créer
une fenêtre translucide. Contrairement aux deux autres méthodes, ceci ne s'applique qu'au background de la
fenêtre parente et les éléments enfants ne sont pas modifiés. Pour utiliser cette option, il faut activer l'attribut
Qt::WA_TranslucentBackground sur le widget parent : setAttribute( Qt::WA_TranslucentBackground,
true);. Sur certains OS comme Windows XP, il est obligatoire d'enlever la décoration avec le flag
Qt::FramelessWindowHint.

Remarque : ces trois méthodes peuvent être utilisées en même temps.

Exemple des différentes possibilités


#include <QtGui>

// base
// drag & drop sur le widget pour le déplacer
// bouton fermer pour fermer l'application
// dessine un dégradé RGBA en fond
class BaseWidget : public QWidget
{
// position dans le repère widget de click gauche
QPoint p;
QPolygon polygon;
QLinearGradient gradient;

public:
BaseWidget()
:QWidget
(
0,
// enlève la décoration Windows et l'entrée dans la barre de tâche
Qt::FramelessWindowHint | Qt::SubWindow
)
{
resize(200,200);

// bouton pour fermer l'application


QPushButton *b = new QPushButton("fermer",this);
QLayout *l= new QVBoxLayout(this);
l->addWidget(b);
connect(b,SIGNAL(clicked()),qApp,SLOT(quit()));
// initialisation du polygone
QVector<QPoint> points;
// même suite aléatoire pour chaque polygone
qsrand(150);
const int nbpoints = 100;

- 129 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Exemple des différentes possibilités


const double r2PI = 2. * 3.14159265;
for (int i = 0 ; i < nbpoints ; ++i)
{
float distance = 80.+20*qrand()/RAND_MAX;
points << QPoint
(
100 + distance*cos(r2PI * i/nbpoints),
100 + distance*sin(r2PI * i/nbpoints)
);
}
polygon = QPolygon (points);

// initialisation du gradient
gradient.setStart (0. , 0.);
gradient.setFinalStop (size().width() , 0.);
{
// Gradienstops pour varier l'apha et la couleur du gradient
QGradientStops gs;
gs <<QGradientStop(0. , QColor(50 , 0 , 50 , 255))
<<QGradientStop(.5 , QColor(0 , 255 , 255 , 100))
<<QGradientStop(1. , QColor(50 , 50 , 0 , 255));

gradient.setStops (gs);
}

}
protected:
void mousePressEvent ( QMouseEvent * mouseEvent )
{
// sauvegarde du point dans le repère widget lors du clic gauche
if(mouseEvent->buttons() == Qt::LeftButton) p = mouseEvent->pos();

}
void mouseMoveEvent ( QMouseEvent * mouseEvent )
{
// repositionne la fênetre en fonction de la postion de la souris
if(mouseEvent->buttons() & Qt::LeftButton) move( mouseEvent->globalPos() - p);
}
protected:
void paintEvent(QPaintEvent * )
{
QPainter p(this);
p.setPen(Qt::NoPen);
// utilisation d'un gradient linéaire entre deux coins de la fenêtre
p.setBrush(gradient);
p.drawPolygon(polygon);
}
};

// widget avec un fond translucide


class TranslucideWidget : public BaseWidget
{
// position dans le repère widget de clic gauche
QPoint p;
public:
TranslucideWidget()
{
// windows avec fond translucide
setAttribute(Qt::WA_TranslucentBackground, true);
}
};

// sidget utilisant un masque


class MaskWidget : public BaseWidget
{
public:

- 130 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Exemple des différentes possibilités


MaskWidget()
{
// création d'un mask sous forme de chessboard.
QBitmap mask(5,5);
{
QPainter p(&mask);
p.fillRect(mask.rect(),Qt::color0);
p.setPen(Qt::color1);
for (int i = 0 ; i < mask.height() ; ++i)
for(int j = 0 ; j< mask.width() ; ++j)
if( !(i%2 ^ j%2))
p.drawPoint(j,i);
}
// retaille le masque à la taille de la fenêtre
mask = mask.scaled(size());
// application du masque sur tout le widget
setMask(mask);
}
};

// widget utilisant windowOpacity


class OpacityWidget : public BaseWidget
{
public:
OpacityWidget()
{
//modifie l'opacite de la fenetre
setWindowOpacity (.5);
}
};

class CompositionWidget : public BaseWidget


{
public:
CompositionWidget()
{
// windows avec fond translucide
setAttribute(Qt::WA_TranslucentBackground, true);

// Création d'un masque en forme de chessboard


QBitmap mask(5,5);
{
QPainter p(&mask);
p.fillRect(mask.rect(),Qt::color0);
p.setPen(Qt::color1);
for (int i = 0 ; i < mask.height() ; ++i)
for(int j = 0 ; j< mask.width() ; ++j)
if( !(i%2 ^ j%2))
p.drawPoint(j,i);
}
// retaille le masque à la taille de la fenêtre
mask = mask.scaled(size());
// application du masque sur tout le widget
setMask(mask);

// modifie l'opacité de la fenêtre


setWindowOpacity (.5);
}
};

int main(int argc, char **argv)


{
QApplication app(argc, argv);
TranslucideWidget translucideWidget;
translucideWidget.show();

- 131 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Exemple des différentes possibilités


translucideWidget.move(50,50);

MaskWidget maskWidget;
maskWidget.show();
maskWidget.move(300,50);

OpacityWidget opacityWidget;
opacityWidget.show();
opacityWidget.move(50,300);

CompositionWidget compositionWidget;
compositionWidget.show();
compositionWidget.move(300 , 300);

return app.exec();
}

Comment changer de style de fenêtre ?


Auteurs : Matthieu Brucher , Benjamin Poulain ,
Par défaut, Qt utilise le style natif du système d'exploitation. Si vous voulez modifier le style, vous pouvez le
faire au niveau de chaque widget à l'aide de QWidget::setStyle() ou au niveau de l'application complète avec
QApplication::setStyle().

Voici, par exemple, comment utiliser le style Plastique pour toute l'application.

QApplication::setStyle(new QPlastiqueStyle);

Remarque : il est possible de créer un style par son nom avec QStyleFactory::create() ou la fonction statique
QApplication::setStyle().

Créer un style complet est généralement une tâche difficile. Heureusement, Qt fournit un mécanisme simple pour
personnaliser les styles : les CSS (Cascading Style Sheets). Avec CSS pour Qt, il est possible de personnaliser le
design d'une application à l'aide d'une syntaxe simple dérivée du CSS. Cela peut se faire au niveau de designer, ou
comme pour les styles classiques, au niveau des widgets ou de l'application.

Une feuille CSS de Qt


QWidget {
border: 1px solid gray;
border-radius: 10px;
padding: 1px 10px 1px 10px;
margin: 3px;
}

QLineEdit:enabled {
background: green;
}
QLineEdit:!enabled {
background: grey;
}
QComboBox::drop-down {
subcontrol-origin: padding;
subcontrol-position: top right;
width: 50px;
border-radius: 0;

- 132 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Une feuille CSS de Qt


}

lien : Exemple de création et d'utilisation de style


lien : Comment connaître les styles disponibles ?

Comment connaître les styles disponibles ?


Auteurs : Benjamin Poulain ,
Les styles disponibles dépendent de la plateforme et des plug-ins. La classe QStyleFactory permet de lever toute
ambiguïté en fournissant la liste des styles disponibles à l'exécutions. La méthode statique QStyleFactory::keys retourne
une liste de nom de style qu'il est possible de charger. À partir des noms de cette liste, il est possible de charger les styles
avec la méthode statique QStyleFactory::create.

En général, il est déconseillé de changer de style, car l'application perd son intégration avec
le reste du système.

Comment mettre une image de fond à un widget ?


Auteurs : Thibaut Cuvelier ,
Il existe trois solutions principales à ce problème. Vous pouvez utiliser un QPixmap dans lequel vous chargez l'image,
que vous imposez à un widget. Alternativement, vous pouvez définir une nouvelle QPalette, lui définir un QBrush qui
contient l'image de fond. Finalement, vous pouvez utiliser les feuilles de style. Voici la manière de les utiliser.

QLabel label;
QPixmap pixmap;

pixmap.load("image.jpg");
label->setPixmap(pixmap);

QWidget widget;
QPalette palette;

palette.setBrush(this->backgroundRole(), QBrush(QImage("image.jpg")));
this->setPalette(palette);

QWidget widget;
QString stylesheet ("QWidget{ background-image: url(image.jpg); }");

widget->setStyleSheet (stylesheet);

Ces solutions peuvent être utilisés sur tous types de widgets : un bouton, un menu, une fenêtre... Elles ne mettront qu'une
image en arrière-plan, elles n'inséreront pas une image dans le widget (comme le bouclier de Windows Vista).

Comment utiliser les feuilles de style ?


Auteurs : Thibaut Cuvelier , Louis du Verdier ,
Qt permet grâce aux feuilles de style de styliser vos widgets grâce à la fonction setStyleSheet(QString &styleSheet).

- 133 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Il est également possible de récupérer cette feuille de style avec la fonction styleSheet(), qui renvoie une variable de type
QString. De plus, les styles appliqués à un widget sont aussi appliqués à ses widgets enfants.

Utilisation toute simple des feuilles de styles


QPushButton *bouton = new QPushButton("Passez la souris ici !", this);
bouton->setStyleSheet("color: blue;");
setStyleSheet("QPushButton { background-color: #FFFFFF } QPushButton:hover { background-color:
#FFD800 } ");

Cibler un widget particulier pour lui appliquer une feuille de style


QPushButton *bouton = new QPushButton("Passez la souris ici !", this);
bouton->setObjectName("Bouton");
setStyleSheet("QPushButton#Bouton { color: blue; background-color: #FFFFFF }"
"QPushButton#Bouton:hover { background-color: #FFD800 } ");

Ici, l'emploi du nom permet d'appliquer une feuille de style à un seul et unique widget.

Cette méthode peut aussi être utilisée sur un QApplication, de sorte que la feuille de style soit
appliquée à la totalité de l'application.

La définition d'une feuille de style sur un widget a pour conséquence que tous les enfants de
celui-ci en héritent. Par exemple, si vous définissez une telle feuille pour un QFrame, tous
les éléments du QFrame en hériteront et seront modifiés en conséquences.

- 134 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sommaire > QtGui > Icônes


Comment utiliser les icônes par défaut de Qt ?
Auteurs : François Jaffré ,
Qt fournit dans son framework des icônes standards comme flèches, fichier, dossiers, lecteur DVD, corbeille, etc. La
récupération de ces icônes se fait à l'aide de la classe QStyle avec la méthode suivante :

QIcon QStyle::standardIcon (StandardPixmap standardIcon, const QStyleOption * option = 0, const


QWidget * widget = 0) const

Qui permet de récupérer l'icône choisi à partir de l'énumération StandardPixmap.

Exemple d'utilisation en appliquant un icône flèche sur un bouton :

//Création d'un contrôle ici un bouton


QPushButton button;
//On récupère un pointeur sur l'objet QStyle correspondant à l'application
QStyle* style = QApplication::style();
//On récupère l'icône désiré ici une flèche pointant vers le haut
QIcon iconFleche = style->standardIcon(QStyle::SP_ArrowUp);
//On applique notre icônes à notre contrôle
button.setIcon(iconFleche);

Comment récupérer les icônes utilisateur des fichiers ?


Auteurs : Louis du Verdier ,
Qt fournit la classe QFileIconProvider qui permet d'obtenir des icônes de fichiers identiques à celles qu'il vous est
possible de trouver dans l'explorateur de votre système d'exploitation. Associé à la classe QFileInfo et/ou à l'énumération
QFileIconProvider::IconType par le biais de la méthode icon(), cette classe vous permettra de récupérer un QIcon
réutilisable sans problème.

QIcon Classe::iconForString(const QString &string)


{
QFileInfo info(string);
if(info.exists())
return QFileIconProvider().icon(info);
else
return QFileIconProvider().icon(QFileIconProvider::File);
}

Dans ce code, nous commençons par émettre une condition vérifiant si le nom de fichier passé en tant qu'argument string
de la fonction correspond bien à un chemin vers un fichier existant. Si c'est le cas, on retourne l'icône de ce fichier telle
qu'on peut la voir dans l'explorateur. Dans le cas contraire, on retourne une icône à partir de l'énumération IconType.

Sous Linux, QFileIconProvider est limité aux icônes définies par IconType. Il est donc
recommandé de passer par QtIconLoader si cela ne vous suffit pas.

- 135 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sommaire > QtXml

- 136 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sommaire > QtXml > DOM


Comment lire un fichier XML avec DOM ?
Auteurs : François Jaffré ,
Qt permet de lire facilement un fichier XML avec l'API DOM. DOM permet de naviguer dans un document XML
comme dans un arbre avec toujours une relation parent enfant entre les noeuds qui composent l'arbre. QDomDocument
permet de gérer les document avec DOM.

Exemple de parcours d'un fichier XML simple.

Fichier xml
<?xml version="1.0" encoding="UTF-8"?>
<root>
<site>
<nom>developpez</nom>
<url>www.developpez.com</url>
</site>
<contributeur>
<nom faq="C++">AAA</nom>
</contributeur>
<contributeur>
<nom faq="Qt">BBB</nom>
</contributeur>
</root>

Parcours du fichier en utilisant l'API DOM


QString fileName = "developpez.xml";
QFile file(fileName);
// Ouverture du fichier en lecture seule et en mode texte
file.open(QFile::ReadOnly | QFile::Text);

QDomDocument doc;
// Ajoute le contenu du fichier XML dans un QDomDocument et dit au QDomDocument de ne pas tenir
compte des namespaces
doc.setContent(&file, false);

// Ici, racine pointe sur l'élément <root> de notre document


QDomElement racine = doc.documentElement();

// Ici, racine pointe sur une fils de <root> c'est à dire <site>
racine = racine.firstChildElement();

//B oucle permettant la navigation dans le fichier XML


while(!racine.isNull())
{
// Si on pointe sur un éléement de type <site>
if(racine.tagName() == "site")
{
// On récupère le premier enfant de l'élément site c'est a dire <nom> ou <url>
QDomElement unElement = racine.firstChildElement();

// On parcourt tous les enfants de l'élément <site>


while(!unElement.isNull())
{
// Si l'enfant de l'élément site est l'élément <nom>
if(unElement.tagName() == "nom")
{
// On récupère le texte contenu dans la balise <nom>
QString strNom = unElement.text();
}
// Si l'enfant de l'élément <site> est <url>
else if(unElement.tagName() == "url")

- 137 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Parcours du fichier en utilisant l'API DOM


{
// On récupère le texte contenu dans la balise <url>
QString strURL = unElement.text();
}
// Permet d'aller au prochain enfant de <site> et de poursuivre la boucle
unElement = unElement.nextSiblingElement();
}
}

// Ici, racine pointe sur un élément <contributeur>


if(racine.tagName() == "contributeur")
{
// On pointe sur l'élément <nom>
QDomElement elem = racine.firstChildElement();

// On récupère le texte de l'élément <nom>


QString strNameContrib = elem.text();

// Récuperation de l'attribut faq de l'élément <nom>


QString attFaq = elem.attribute("faq");
}

// On va a l'élément fils de <root> suivant


racine = racine.nextSiblingElement();
}

Comment écrire un fichier XML avec DOM ?


Auteurs : François Jaffré ,
Qt fournit la classe QDomDocument, qui permet de gérer les fichiers XML à la manière de DOM, c'est-à-dire que le
fichier XML est représenté par un arbre dans lequel on peut se déplacer grâce à une relation de parent-enfant entre les
noeuds qui composent l'arbre. Avec QDomDocument vous pouvez soit créer un fichier XML en partant de rien, mais
vous pouvez aussi éditer un fichier existant (ajout de noeuds, modification de texte...).

Exemple de création d'un fichier XML à l'aide de l'API DOM de Qt.

fichier xml
<?xml version="1.0" encoding="UTF-8"?>
<root>
<site>
<nom>developpez</nom>
<url>www.developpez.com</url>
</site>
<contributeur>
<nom faq="c++">AAA</nom>
</contributeur>
<contributeur>
<nom faq="Qt">BBB</nom>
</contributeur>
</root>

écriture avec DOM


// Objet de base servant à la création de notre fichier XML
QDomDocument doc;

// Création de l'en-tête du fichier XML : <?xml version="1.0" encoding="UTF-8"?>


QDomNode xmlNode = doc.createProcessingInstruction("xml","version=\"1.0\" encoding=\"UTF-8\"");

- 138 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

écriture avec DOM


// On insère cet en-tête avant le premier enfant
doc.insertBefore(xmlNode, doc.firstChild());

// Création de l'élément <root>


QDomElement root = doc.createElement("root");

// On ajoute l'élément <root> en tant que premier enfant de notre document


doc.appendChild(root);

// Création de l'élément <site>


QDomElement site = doc.createElement("site");

// On ajoute l'élément <site> en tant que premier enfant de l'élément <root>


root.appendChild(site);

// Création de l'élément <nom>


QDomElement nom = doc.createElement("nom");

// On ajoute l'élément <nom> en tant que premier enfant de l'element <site>


site.appendChild(nom);

// Création du texte qui sera entre les balises <nom> </nom>


QDomText nomText = doc.createTextNode("developpez");

// On ajoute ce texte à l'élément <nom>


nom.appendChild(nomText);

// Création de l'élément <url>


QDomElement url = doc.createElement("url");

// On ajoute l'élément <url> en tant que deuxième enfant de l'élément <site>


site.appendChild(url);

// Création du texte qui sera entre les balises <url> </url>


QDomText urlText = doc.createTextNode("www.developpez.com");

// On ajoute ce texte à l'élément <url>


url.appendChild(urlText);

//Création de l'élément <contributeur>


QDomElement contributeur1 = doc.createElement("contributeur");

// Création de l'élément <nom>


QDomElement nomContrib1 = doc.createElement("nom");

// Ajout de l'attibut "faq" qui aura la valeur "C++" à l'élément <nom>


nomContrib1.setAttribute( "faq","C++");

// On ajoute l'élément <contributeur> en tant qu'enfant de l'élément <root>


root.appendChild(contributeur1);

// On ajoute l'élément <nom> en tant qu'enfant de l'élément <contributeur>


contributeur1.appendChild(nomContrib1);

// Création du texte qui sera dans la balise <nom>


QDomText nameContrib1 = doc.createTextNode("AAA");

// On ajoute ce texte à l'élément <nom>


nomContrib1.appendChild(nameContrib1);

// Création de l'élément <contributeur>


QDomElement contributeur2 = doc.createElement("contributeur");

// Création de l'élément <nom>


QDomElement nomContrib2 = doc.createElement("nom");

// Ajout de l'attibut "faq" qui aura la valeur "Qt" à l'élément <nom>

- 139 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

écriture avec DOM


nomContrib2.setAttribute("faq","Qt");

// On ajoute l'élément <contributeur> en tant qu'enfant de l'élément <root>


root.appendChild(contributeur2);

// On ajoute l'elemnt <nom> en tant qu'enfant de l'élément <contributeur>


contributeur2.appendChild(nomContrib2);

// Création du texte qui sera entre les balises <nom> </nom>


QDomText nameContrib2 = doc.createTextNode("BBB");

// On ajoute ce texte à l'élément <nom>


nomContrib2.appendChild(nameContrib2);

// Création du fichier XML de sortie


QFile file( "developpez.xml" );

// Ouverture de ce fichier en lecture seule


file.open(QIODevice::WriteOnly);

// On crée une QTextStream a partir de ce fichier


QTextStream ts(&file);

// Valeur servant au nombre de caractères pour l'indentation du fichier XML


int indent = 2;

// On sauvegarde le fichier XML en precisant l'indentation desirée


doc.save(ts, indent);

- 140 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sommaire > QtXml > SAX


Comment lire un fichier XML avec QXmlStreamReader ?
Auteurs : François Jaffré ,
Qt fourni, depuis sa version 4.3, la classe QXmlStreamReader qui permet de lire rapidement des fichiers XML un peu
à la manière de SAX mais en non événementiel. Comme SAX, on parcourt l'arbre XML et l'on ne peut le remonter
pendant son parcours. QXmlStreamReader repose sur le principe d'une boucle dans laquelle on va parcourir le fichier
à l'aide de la méthode readNext() et vérifier sur quel type de token on est positionné.

Exemple avec le fichier XML


<developpez>
<contributeur>Superjaja</contributeur>
</developpez>

Si l'on parcourt le fichier avec la méthode readNext(), les différents types de token renvoyés sont:

• StartDocument
• StartElement (name() == "developpez")
• StartElement (name() == "contributeur")
• Characters (text() == "Superjaja")
• EndElement (name() == "contributeur")
• EndElement (name() == "developpez")
• EndDocument

Pour connaître tout les types de tokens possible, se référer à la documentation de Qt.

Voici un exemple un peu plus complexe

Fichier XML
<?xml version="1.0" encoding="UTF-8"?>
<root>
<site>
<nom>developpez</nom>
<url>www.developpez.com</url>
</site>
<contributeur>
<nom faq="c++">Alp</nom>
</contributeur>
<contributeur>
<nom faq="Qt">Yan</nom>
</contributeur>
</root>

Parcours de ce fichier avec QXmlStreamReader


QXmlStreamReader reader; // Objet servant à la navigation
QString fileName = "developpez.xml";
QFile file(fileName);
file.open(QFile::ReadOnly | QFile::Text); // Ouverture du fichier XML en lecture seule et en mode
texte
reader.setDevice(&file); // Initialise l'instance reader avec le flux XML venant de file

//Le but de cette boucle est de parcourir le fichier et de vérifier si l'on est au début d'un
élément.
reader.readNext();
while (!reader.atEnd())

- 141 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Parcours de ce fichier avec QXmlStreamReader


{
if (reader.isStartElement())
{
if (reader.name() == "root")
{
reader.readNext(); // On va au prochain token
// Tant que celui-ci n'est pas un élément de départ on avance au token suivant
while(reader.isStartElement()==false)
reader.readNext();

if(reader.name() == "site")
{
reader.readNext();
while(reader.isStartElement()==false)
reader.readNext();
if(reader.name() == "nom")
{
QString strNom = reader.readElementText();
reader.readNext();
while(reader.isStartElement()==false)
reader.readNext();
}
if(reader.name() == "url")
{
QString strUrl = reader.readElementText();
}

}
}

if(reader.name() == "contributeur")
{
reader.readNext();
while(reader.isStartElement()==false)
reader.readNext();
if(reader.name() == "nom")
{
QString attrFAQ = reader.attributes().value("faq").toString();
QString strNameContrib = reader.readElementText();
}
}
}
reader.readNext(); // On va au prochain token
}
file.close();

Comment écrire un fichier XML avec QXmlStreamWriter ?


Auteurs : François Jaffré ,
Qt, depuis sa version 4.3, fournit la classe QXmlStreamWriter pour écrire des fichiers XML. Celle-ci est relativement
simple et fonctionne sur le même principe que QXmlStreamReader pour la lecture.

On souhaite écrire le fichier XML suivant :

Fichier XML
<?xml version="1.0" encoding="UTF-8"?>
<root>
<site>
<nom>developpez</nom>
<url>www.developpez.com</url>

- 142 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Fichier XML
</site>
<contributeur>
<nom faq="c++">AAA</nom>
</contributeur>
<contributeur>
<nom faq="Qt">BBB</nom>
</contributeur>
</root>

Réalisation avec QXmlStreamWriter


QString fileName = "developpez.xml";
QFile file(fileName);
// Ouverture du fichier en écriture et en texte.
file.open(QFile::WriteOnly | QFile::Text);
QXmlStreamWriter writer(&file);

// Permet l'indentation du fichier XML


writer.setAutoFormatting(true);

// Écrit l'en-tête du fichier XML : <?xml version="1.0" encoding="UTF-8" ?>


writer.writeStartDocument();

// Élément racine du fichier XML


writer.writeStartElement("root");

// Ajoute l'élément site


writer.writeStartElement("site");

// Ajoute l'élément nom et lui applique le texte "developpez" et ferme l'élément nom
writer.writeTextElement("nom", "developpez");

// Ajoute l'élément url et lui applique le texte "www.developpez.com" et ferme l'élément url
writer.writeTextElement("url", "www.developpez.com");

// Ferme l'élément site


writer.writeEndElement();

// Ajoute l'élément contributeur


writer.writeStartElement("contributeur");

// Ajoute l'élément nom


writer.writeStartElement("nom");

// Ajoute un attribut a l'élément nom


writer.writeAttribute("faq", "c++");

// Ajout du texte à l'élément nom


writer.writeCharacters("AAA");

// Ferme l'élément nom


writer.writeEndElement();

// Ferme l'élément contributeur


writer.writeEndElement();

// Ajoute l'élément contributeur


writer.writeStartElement("contributeur");

// Ajoute l'élément nom


writer.writeStartElement("nom");

// Ajoute un attribut à l'élément nom


writer.writeAttribute("faq", "Qt");
writer.writeCharacters("BBB");

- 143 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Réalisation avec QXmlStreamWriter


// Ferme l'élément nom
writer.writeEndElement();
//Ferme l'élément contributeur
writer.writeEndElement();

// Finalise le document XML


writer.writeEndDocument();

// Fermer le fichier pour bien enregistrer le document et ferme l'élément root


file.close();

- 144 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sommaire > QNetwork


Comment retrouver l'IP d'un domaine et vice versa ?
Auteurs : François Jaffré ,
Qt fournit, dans son module réseau, la classe QHostInfo, qui permet de retrouver l'adresse IP correspondant à un nom
de domaine, mais aussi, si possible, de retrouver le domaine correspondant à l'IP. Dans ce but QHostInfo- possède les
méthodes statiques suivantes :

- 145 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

• int QHostInfo::lookupHost ( const QString & name, QObject * receiver, const char * member) : permet
retrouver le nom de domaine à partir d'une IP ou vice versa de manière asynchrone (non bloquante).
• QHostInfo QHostInfo::fromName (const QString & name) : permet de retrouver l'IP appartenant au domaine
et vice versa de manière synchrone (bloquante).

Exemple
#include <QApplication>
#include <Qlabel>
#include <QVBoxLayout>
#include <QPushButton>
#include <QLabel>
#include <QLineEdit>

class ResolveDNS : public QWidget


{
Q_OBJECT
QLabel* m_Label_Domain;
QLabel* m_Label_Ip;
QLineEdit* m_Line_Domain;
QLineEdit* m_Line_Ip;
QPushButton* m_Button_Ip;
QPushButton* m_Button_Domain;

public :
ResolveDNS() // Constructeur
{
// Création des differents contôles
m_Label_Domain = new QLabel("&Domain :", this);
m_Label_Ip = new QLabel("&Ip :", this);
m_Line_Domain = new QLineEdit(this);
m_Line_Ip = new QLineEdit(this);

m_Label_Domain->setBuddy(m_Line_Domain);
m_Label_Ip->setBuddy(m_Line_Ip);
m_Button_Ip = new QPushButton("Resolve IP",this);
m_Button_Domain = new QPushButton("Resolve Domain",this);

// Gestion du layout
QHBoxLayout* Layout = new QHBoxLayout();
Layout->addWidget(m_Label_Domain);
Layout->addWidget(m_Line_Domain);
Layout->addWidget(m_Label_Ip);
Layout->addWidget(m_Line_Ip);
Layout->addWidget(m_Button_Domain);
Layout->addWidget(m_Button_Ip);
setLayout(Layout);

// Connexions des différents signaux et slots pour la gestion des boutons


connect(this->m_Button_Ip, SIGNAL(clicked(bool)), this, SLOT(resolveIp(bool)));
connect(this->m_Button_Domain, SIGNAL(clicked(bool)), this, SLOT(resolveDomain(bool)));
}
private slots :
void resolveDomain(bool valid) // Clic sur "Resolve Domain"
{
// Résolution domaine -> IP (mode synchrone)
QHostInfo infoAdresse = QHostInfo::fromName(m_Line_Domain->text());
QList<QHostAddress> result_adresses = infoAdresse.addresses();
QString Ip;
// Si plusieurs adresses correspondent à un même domaine
for(int i=0; i < result_adresses.size(); i++)
{
// On crée une chaine qui contient toutes les adresses IP
Ip = Ip + result_adresses.at(i).toString() +"; ";
}
// Affichage dans l'edit
m_Line_Ip->setText(Ip);

- 146 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Exemple
}

// Clic sur "Resolve IP"


void resolveIp(bool valid)
{
// Résolution IP -> domaine si possible de manière asynchrone
QHostInfo::lookupHost(m_Line_Ip->text(),this, SLOT(resolveIpFinish(QHostInfo)));
}

// Slot appelé à la fin de la résolution IP -> domaine (mode asynchrone)


void resolveIpFinish(const QHostInfo& infoAdresse)
{
// Affichage dans l'édit
m_Line_Domain->setText(infoAdresse.hostName());
}
};

#include "main.moc"

int main(int argc, char *argv[])


{
QApplication a(argc, argv);
ResolveDNS w;
w.show();
return a.exec();
}

Comment utiliser un proxy ?


Auteurs : Thibaut Cuvelier ,
Qt nous fournit une classe, QNetworkProxy, qui représente un proxy. Vous pouvez en spécifier un à votre gestionnaire
QNetworkAccessManager grâce à sa méthode setProxy(). Ce proxy peut être aussi utilisé par d'autres classes, plus
anciennes, à chaque fois grâce à la méthode setProxy() : QHttp, QFtp, QAbstractSocket, QTcpSocket, QUdpSocket,
QTcpServer...

Voici un exemple de création de proxy, assez explicite.

QNetworkProxy proxy;
proxy.setType(QNetworkProxy::Socks5Proxy);
proxy.setHostName("proxy.exemple.com");
proxy.setPort(1080);
proxy.setUser("username");
proxy.setPassword("password");

Le type du proxy est choisi dans l'énumération QNetworkProxy::ProxyType, que voici.

enum ProxyType { NoProxy, DefaultProxy, Socks5Proxy, HttpProxy,


HttpCachingProxy, FtpCachingProxy }

DefaultProxy oblige l'utilisation du proxy par défaut.

Maintenant, nous allons voir comment demander à un objet de passer par un proxy. Nous nous considérerons à la suite
de l'exemple de création d'un proxy.

QNetworkAccessManager manager ();


manager->setProxy (proxy);

- 147 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

QWebView * view = new QWebView () ;


view->page()->networkAccessManager()->setProxy(proxy);

lien : Comment définir un proxy par défaut ?

- 148 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sommaire > QNetwork > QHttp


Comment télécharger une page web avec QHttp ?
Auteurs : François Jaffré ,
Qt a encapsulé le protocole HTTP au sein de la classe QHttp. Celle-ci possède notamment les méthodes suivantes :

- 149 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

• int post ( const QString & path, QIODevice * data, QIODevice * to = 0) : permet l'envoi de données ;
• int get ( const QString & path, QIODevice * to = 0) : permet la réception des données ;
• int close () : ferme la connexion.

Téléchargement d'une page web


#include <QApplication>
#include <QPushButton>
#include <QGridLayout>
#include <QProgressBar>
#include <QLabel>
#include <QLineEdit>
#include <QHBoxLayout>
#include <QHBoxLayout>
#include <QHttp>
#include <QFile>
#include <QUrl>
#include <QMessageBox>
#include <QFileDialog>

class FAQHttp : public QWidget


{
Q_OBJECT
QPushButton *m_Bouton_Dowload; // Bouton "Download"
QProgressBar *m_ProgressBar; // Sert à afficher la progression du téléchargement
QLineEdit *m_Edit; // Chemin de l'URL de téléchargment
QLabel *m_Label;
QHttp *m_http; // Permet la gestion du téléchargement via HTTP
QFile *m_file; // Fichier de fin du téléchargement
int m_httpId; // Contient l'ID de notre requête HTTP
public :
FAQHttp()
{
// Création des contrôles de types boutons, Edit, Label, ProgressBar
this->m_Bouton_Dowload = new QPushButton("Télécharger",this);
this->m_ProgressBar = new QProgressBar(this);
this->m_Edit = new QLineEdit(this);
this->m_Label = new QLabel("URL:", this);
m_Label->setBuddy(m_Edit);

// Gestion du layout pour le placement des boutons


QHBoxLayout *firstLayout = new QHBoxLayout;
firstLayout->addWidget(m_Label);
firstLayout->addWidget(m_Edit);

QHBoxLayout *Layout = new QHBoxLayout;


Layout->addLayout(firstLayout);
Layout->addWidget(m_Bouton_Dowload);

QVBoxLayout *secondeLayout = new QVBoxLayout();


secondeLayout->addLayout(Layout);
secondeLayout->addWidget(m_ProgressBar);
setLayout(secondeLayout);

// On connecte les differents signaux et slots pour les boutons


connect(this->m_Bouton_Dowload, SIGNAL(clicked(bool)), this, SLOT(click_Download(bool)));
resize(400, 150);//Gestion de la taille de la fenêtre
}

private slots:

void DownloadFile(QString source , QString fichier)


{
QUrl adresse(source);
this->m_http = new QHttp(adresse.host(),80,this);
m_file = new QFile(fichier);

- 150 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Téléchargement d'une page web


if(!m_file->open(QIODevice::WriteOnly)) // On vérifie qu'il n'y a pas de problème lors de
l'ouverture du fichier
{
QMessageBox::information(this, "HTTP Problemes"," Probleme lors du telechargement");
// On fait le ménage en mémoire
delete this->m_http;
delete this->m_file;
return;
}
// On fait la requette et on en récupère l'Id
m_httpId = m_http->get(adresse.toString(), m_file);

// On connecte les signaux slots pour avoir l'état d'avancement du telechargement


connect(m_http,SIGNAL(requestFinished(int, bool)),this,SLOT(finish_dowload(int ,bool)));
connect(m_http,SIGNAL(dataSendProgress(int,int)),this,SLOT(progress_dowload(int, int)));
this->m_ProgressBar->reset();
this->m_ProgressBar->setMinimum(0);
}

// Est déclenché à la fin du téléchargement


void finish_dowload(int httpId, bool error)
{
if (this->m_httpId != httpId)
{
return;
}
else
{
if(error)
QMessageBox::information(this, "HTTP Problèmes"," Probleme lors du téléchargement");
else
QMessageBox::information(this, "HTTP"," Le téléchargement a réussi");

this->m_file->close(); // On ferme le fichier une fois le téléchargement terminé


// On fait le ménage au niveau mémoire
delete this->m_http;
delete this->m_file;
}
}

// Bouton "Start" "Stop"


void click_Download(bool valid)
{
QString saveFile = QFileDialog::getSaveFileName(this,"Download Files","C:\\", "All Files
(*.*)");
if(!saveFile.isEmpty())
DownloadFile(this->m_Edit->text(),saveFile);
}

// Permet de suivre l'avancée du téléchargement


void progress_dowload(int done , int total)
{
this->m_ProgressBar->setMaximum(total);
this->m_ProgressBar->setValue(done); // On incrémente la progress bar en fonction des
données téléchargées
}

};

#include "main.moc"

int main(int argc, char *argv[])


{
QApplication a(argc, argv);
FAQHttp w;
w.show();

- 151 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Téléchargement d'une page web


return a.exec();
}

Remarque 1 : cette classe possède de nombreux signaux qui permettrent de suivre l'état de la connexion avec le serveur.
Référez-vous à la doc pour plus d'information.
Remarque 2: depuis Qt 4.4, QHttp est déprécié au profit des classes QNetworkAccessManager et QNetworkReply, qui
offrent plus de souplesse que QHttp.

Comment exécuter une requête simple sur un serveur avec la méthode GET ?
Auteurs : LittleWhite ,
Pour exécuter une requête, nous avons besoin de deux choses : QHttp et QUrl.

QHttp permet de faire la requête proprement dite, alors que QUrl simplifie l'interaction avec les données pour se
connecter au serveur (son adresse, son port ainsi la sécurisation (HTTPS) ou non de la connexion).

Il faut aussi connecter le slot requestFinished(int, bool) afin de récupérer les données renvoyées par le serveur.

Pour simplifier le travail nous pouvons hériter de la classe QHttp afin de créer notre classe Client. Celle ci contiendra
une fonction connexion afin de faire la requête.

#include <QHttp>
#include <QUrl>

class Client : public QHttp


{
Q_OBJECT

private:

QUrl url;
int idRequete;

public slots:

void recuperationResultat(int id, bool error)


{
if ( error )
// Il y a eu une erreur pendant la requête
return;

// Nous vérifions si la requête est celle que nous voulons (dans le cas où plusieurs requête
sont en cours)
if ( id == idRequete )
// Ici on peut mettre un code pour récupérer les données renvoyées par le serveur dans
un QByteArray
this->readAll();
}

public:

Client(const QString& urlSite)


{
url = QUrl(urlSite); // On enregistre l'URL du site
idRequete = 0;

// Connexion du signal de fin de requête avec notre analyseur de résultat

- 152 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

connect(this, SIGNAL(requestFinished(int, bool)), this, SLOT(recuperationResultat(int,


bool)));
}

void connexion(void)
{

this->setHost ( url.host(),
// on détermine si c'est une connection sécurisée
( url.scheme().toLower() == "https" ) ? QHttp::ConnectionModeHttps :
QHttp::ConnectionModeHttp,
url.port() == -1 ? 0 : url.port() // On determine le port
);

idRequete = this->get(url.path(),0); // La requête est lancée


}
};

Comment exécuter une requête avec envoie d'information sur un serveur avec la méthode GET ?
Auteurs : LittleWhite ,
Pour exécuter une requête plus évoluée, nous avons besoin de trois choses : QHttp, QUrl et QHttpRequestHeader

QHttp exécute la requête proprement dite, alors que QUrl simplifie l'interaction avec les données de connexion au
serveur à contacter (son adresse, son port ainsi la sécurisation (HTTPS) ou non de la connexion). QHttpRequestHeader
ajoute des informations sur notre connexion. Grâce à cette classe, nous pouvons passer des cookies ou encore changer
le user-agent (qui permet d'identifier le navigateur).

Il faut aussi connecter le slot requestFinished(int, bool) afin de récupérer les données renvoyées par le serveur.

Pour simplifier le travail nous pouvons hériter de la classe QHttp afin de créer notre classe Client. Celle ci contiendra
une fonction connexion afin de faire la requête.

#include <QHttp>
#include <QUrl>

class Client : public QHttp


{
Q_OBJECT

private:

QUrl url;
int idRequete;

public slots:

void recuperationResultat(int id, bool error)


{
if ( error )
// Il y a eu une erreur pendant la requête
return;

// Nous vérifions si la requête est celle que nous voulons (dans le cas où plusieurs requête
sont en cours)
if ( id == idRequete )
// Ici on peut mettre un code pour récupérer les données renvoyées par le serveur dans
un QByteArray
this->readAll();
}

- 153 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

public:

Client(const QString& urlSite)


{
url = QUrl(urlSite); // On enregistre l'URL du site
idRequete = 0;

// Connexion du signal de fin de requete avec notre analyseur de résultat


connect(this, SIGNAL(requestFinished(int, bool)), this, SLOT(recuperationResultat(int,
bool)));
}

void connexion(void)
{

this->setHost ( url.host(),
// on détermine si c'est une connexion sécurisée
( url.scheme().toLower() == "https" ) ? QHttp::ConnectionModeHttps :
QHttp::ConnectionModeHttp,
url.port() == -1 ? 0 : url.port() // On détermine le port
);

// Ici nous créons l'entête pour notre requête


QHttpRequestHeader reqHeader("GET", "http://qt.nokia.com");
reqHeader.setValue("Host", "http://qt.nokia.com");
reqHeader.setValue("User-Agent", "Nom que vous voulez");
reqHeader.setValue("Cookie", "idducookie"); // Permet de passer un cookie pour être reconnu
par le serveur

idRequete = this->request(reqHeader);
}
};

Si vous utilisez Firefox, et que vous ne savez pas quoi mettre dans l'en-tête, vous pouvez
utiliser LiveHTTPHeaders qui affichera les information des en-têtes envoyés et reçus par le
navigateur.

lien : LiveHttpHeaders

Comment exécuter une requête avec envoi d'informations sur un serveur avec la méthode POST ?
Auteurs : LittleWhite ,
Une requête POST permet, par exemple, de se connecter à un site web en envoyant un identifiant et un mot de passe.

Pour exécuter une requête POST, nous avons besoin de trois choses : QHttp, QUrl et QHttpRequestHeader

QHttp exécute la requête proprement dite, alors que QUrl simplifie l'interaction avec les données de connexion au
serveur à contacter (son adresse, son port ainsi la sécurisation (HTTPS) ou non de la connexion). QHttpRequestHeader
ajoute des informations sur notre connexion. Grâce à cette classe, nous pouvons passer des cookies ou encore changer
le user-agent (qui permet d'identifier le navigateur).

Il faut aussi connecter le slot requestFinished(int, bool) afin de récupérer les données renvoyées par le serveur.

Pour simplifier le travail nous pouvons hériter de la classe QHttp afin de créer notre classe Client. Celle ci contiendra
une fonction connexion afin de faire la requête.

#include <QHttp>
#include <QUrl>

- 154 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

class Client : public QHttp


{
Q_OBJECT

private:

QUrl url;
int idRequete;

public slots:

void recuperationResultat(int id, bool error)


{
if ( error )
// Il y a eu une erreur pendant la requête
return;

// Nous vérifions si la requête est celle que nous voulons (dans le cas où plusieurs requête
sont en cours)
if ( id == idRequete )
// Ici on peut mettre un code pour récupérer les données renvoyées par le serveur dans
un QByteArray
this->readAll();
}

public:

Client(const QString& urlSite)


{
url = QUrl(urlSite); // On enregistre l'url du sire
idRequete = 0;

// Connexion du signal de fin de requete avec notre analyseur de résultat


connect(this, SIGNAL(requestFinished(int, bool)), this, SLOT(recuperationResultat(int,
bool)));
}

void connexion(void)
{
this->setHost ( url.host(),
// on détermine si c'est une connexion sécurisée
( url.scheme().toLower() == "https" ) ? QHttp::ConnectionModeHttps :
QHttp::ConnectionModeHttp,
url.port() == -1 ? 0 : url.port() // On détermine le port
);

// Prépare une chaîne qui contiendra les éléments pour la connexion


QString searchString = QString("username=") + QString("toto") + QString("&password=") +
QString("tata");

// Ici nous créons l'en-tête pour notre requête


QHttpRequestHeader postRequest("POST", "http://qt.nokia.com");
postRequest.setValue("Host", "http://qt.nokia.com");
postRequest.setValue("User-Agent", "Nom du navigateur");

// Requête avec le passage des identifiants


idRequete = this->request(postRequest,searchString.toUtf8());
}
};

- 155 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Si vous utilisez Firefox, et que vous ne savez pas quoi mettre dans l'en-tête, vous pouvez
utiliser LiveHTTPHeaders qui affichera les information des en-têtes envoyés et reçus par le
navigateur.

lien : LiveHttpHeaders

Comment récupérer un cookie avec QHttp ?


Auteurs : LittleWhite ,
Pour récupérer un cookie, nous avons besoin de quatre choses : QHttp, QUrl, QHttpRequestHeader et
QHttpResponseHeader.

QHttp exécute la requête proprement dite, alors que QUrl simplifie l'interaction avec les données de connexion au
serveur à contacter (son adresse, son port ainsi la sécurisation (HTTPS) ou non de la connexion). QHttpRequestHeader
ajoute des informations sur notre connexion. Grâce à cette classe, nous pouvons passer des cookies ou encore changer le
user-agent (qui permet d'identifier le navigateur). QHttpResponseHeader doit être analysé afin de récupérer le cookie.

Il faut connecter le slot requestFinished(int, bool) afin de récupérer les données renvoyées par le serveur, et le slot
responseHeaderReceived(const QHttpResponseHeader&) pour récupérer l'en-tête de réponse du serveur.

Pour simplifier le travail nous pouvons hériter de la classe QHttp afin de créer notre classe Client. Celle ci contiendra
une fonction connexion afin de faire la requête.

#include <QHttp>
#include <QUrl>

class Client : public QHttp


{
Q_OBJECT

private:

QUrl url;
int idRequete;

public slots:

void recuperationResultat(int id, bool error)


{
if ( error )
// Il y a eu une erreur pendant la requête
return;

// Nous vérifions si la requête est celle que nous voulons (dans le cas où plusieurs requête
sont en cours)
if ( id == idRequete )
// Ici on peut mettre un code pour récupérer les données renvoyées par le serveur dans
un QByteArray
this->readAll();
}

void Client :: recuperationCookie(const QHttpResponseHeader& header)


{

// Ce test est tiré de la norme RFC 1945


if ( header.reasonPhrase() == QString("FOUND") && header.statusCode() >= 300 &&
header.statusCode() <= 399 )
{
// Récupération du cookie
cookie = header.value("Set-Cookie");

- 156 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

}
else
{
// Il est possible que les identifiants ne soient pas bons...
}
}

public:

Client(const QString& urlSite)


{
url = QUrl(urlSite); // On enregistre l'url du sire
idRequete = 0;

// Connexion du signal de fin de requête avec notre analyseur de résultat


connect(this, SIGNAL(requestFinished(int, bool)), this, SLOT(recuperationResultat(int,
bool)));

// Connexion du signal de réponse du serveur avec notre analyseur de résultat


connect( this, SIGNAL(responseHeaderReceived(const QHttpResponseHeader&) ),
this, SLOT (recuperationCookie (const QHttpResponseHeader&) ) );
}

void connexion(void)
{

this->setHost ( url.host(),
// on détermine si c'est une connection sécurisée
( url.scheme().toLower() == "https" ) ? QHttp::ConnectionModeHttps :
QHttp::ConnectionModeHttp,
url.port() == -1 ? 0 : url.port() // On determine le port
);

// Prépare une chaîne qui contiendra les éléments pour la connexion


QString searchString = QString("username=") + QString("toto") + QString("&password=") +
QString("tata");

// Ici nous créons l'en-tête pour notre requête


QHttpRequestHeader postRequest("POST", "http://qt.nokia.com");
postRequest.setValue("Host", "http://qt.nokia.com");
postRequest.setValue( "User-Agent", "Nom du navigateur");

// Requête avec le passage des identifiants


idRequete = this->request(postRequest,searchString.toUtf8());
}
};

Si vous utilisez Firefox, et que vous ne savez pas quoi mettre dans l'en-tête, vous pouvez
utiliser LiveHTTPHeaders qui affichera les information des en-têtes envoyés et reçus par le
navigateur.

lien : LiveHttpHeaders

- 157 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sommaire > QNetwork > Sockets


Pourquoi les nombres de paquets émis et reçus avec QTcpSocket diffèrent-il ?
Auteurs : nouknouk ,
Une erreur (très) courante est de croire qu'on recevra systématiquement le même nombre de paquets que le nombre
de ceux qu'on a envoyé.

Un exemple concret : l'ordinateur A (émetteur) fait trois appels successifs à la fonction write() pour envoyer des données
à l'ordi B (récepteur).

• 1er appel, il écrit 5 octets (ABCDE) ;


• 2ème appel, il écrit 2 octets (FG) ;
• 3ème appel, il écrit 3 octets (HIJ).

On sait que, chaque fois que B va recevoir des données, il émettra le signal readyRead() et que le slot qui y est connecté
pourra appeler une fonction, du type readAll() pour récupérer tout ce qu'on vient de recevoir.

La première idée qui vient à l'esprit c'est que, comme A a appelé trois fois la fonction write(), B émettra 3 fois
readyRead() et que les trois appels à readAll() retourneront ABCDE puis FG puis HIJ.

Cette manière de penser ne s'applique pas toujours.

En effet, il se peut très bien que l'on reçoive le tout :

• En une seule fois : une seule émission du signal readyRead() et readAll() retourne ABCDEFGHIJ ;
• En 4 fois : 4 émissions de readyRead() et readAll() retourne AB puis C puis DEFGH puis IJ ;
• En 3 fois, en 10 fois, etc.

Il y a plusieurs raisons à cela.

• Pour les gros paquets, les couches réseaux inférieures à TCP (Ethernet...) ne savent pas transporter des paquets
d'une taille trop grande (1500 octets, en-têtes compris par défaut pour Ethernet). Donc l'envoi d'un seul gros
paquet de données a toutes les chances d'être subdivisé en plusieurs paquets et donc d'être reçu en plusieurs fois
côté récepteur. Or, la taille maximale d'un paquet avant qu'il ne soit découpé ne peut être prévue à l'avance : ça
dépend de la configuration de l'ensemble des routeurs situés entre l'émetteur et le récepteur. De plus, pendant
une même connexion, il se peut que les paquets empruntent des chemins différents, donc passent par des
routeurs différents... donc la taille maximale peut varier dans le temps. Imprévisible, donc.
• Pour les petits paquets, à l'inverse peuvent se voir regroupés en un seul paquet : si l'émetteur veut envoyer une
dizaine de petits paquets dans un intervalle de temps très court (exemple : dix appels à write() successifs avec
2 octets écrits à chaque appel). L'interface réseau est une grande maligne qui va optimiser leur émission en
les envoyant tous d'un coup pour économiser de la bande passante. En effet, un paquet TCP est typiquement
composé d'un en-tête (origine, destination, port...) d'environ 20 octets suivi des données utiles (2 octets dans
notre exemple). Au lieu d'envoyer 10 paquets, donc 10 entêtes et 10 bouts de données, soit 10 x (20+2) = 220
octets, il va envoyer un seul paquet avec toutes les données, ce qui fera en tout un seul en-tête et 10x2 octets de
données, soit 40 octets, soit plus de 80% de bande passante économisée ! Ce mécanisme d'optimisation s'appelle
l'algorithme de Nagle et peut être désactivé pour des besoins spécifiques.

En résumé, les seules choses que TCP est capable de garantir sont que :

- 158 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

1 Quoiqu'il arrive, on recevra un jour où l'autre tous nos paquets (sauf si bien entendu entre temps un des
deux ordinateurs se déconnecte). Par contre, le temps de transmission n'est pas garanti. Cela peut prendre 1
microseconde comme une heure.
2 Quoiqu'il arrive, l'ordre de réception sera le même que celui d'émission (A, puis B, puis C, etc.).
3 Quoiqu'il arrive, les données reçues seront strictement identiques à celles émises (on ne recevra pas N à la place
de B).

lien : Quelles solutions pour pouvoir différencier mes blocs de données ?

Quelles solutions pour pouvoir différencier mes blocs de données ?


Auteurs : nouknouk ,
On voit bien que, quoi qu'on fasse, on ne pourra pas garantir que le nombre de paquets reçus sera toujours égal au
nombre de paquets émis.

En effet, même en désactivant l'algorithme de Nagle, on garantit que le nombre de paquets reçus sera au moins égal au
nombre de paquets émis, mais rien ne nous garantis que les routeurs intermédiaires ne vont pas fragmenter un paquet
en deux sous-paquets.

Donc pas de solution immédiate, il va faut se confectionner sa propre petite solution. Il y a deux solutions relativement
simples et classiques qui conviennent dans la majorité des cas.

• Pour chaque bloc de données que l'émetteur envoie, on va systématiquement le terminer avec un ou plusieurs
caractères supplémentaires qui annonceront la fin du bloc (un marqueur).

Par exemple, en admettant qu'on transmet du texte, on décide que le marqueur sera le caractère de retour à la ligne
(\n'). Côté récepteur, quand on reçoit les données, on les stocke dans un buffer jusqu'à ce qu'on trouve le marqueur
(\n'). Quand on l'a trouvé, on prend tous les caractères reçus jusque là, et on a un bloc entier de données. Les caractères
qui suivront représenteront le début du bloc suivant.

Cette méthode a l'avantage d'être très simple. Son principal inconvénient est qu'il faille trouver un marqueur qu'on
est certain de ne jamais voir apparaître dans les vraies données. En effet, l'exemple ci-dessus fonctionne parfaitement...
tant que les blocs de données eux-mêmes ne contiennent pas de retour chariot.

• La technique de pré-déclaration de la taille du paquet : lorsque l'émetteur désire envoyer un bloc de données, il
va commencer par calculer la taille totale du bloc en octets, puis va écrire cette taille sur la socket (par exemple
sous la forme de 4 octets représentant un int) avant d'écrire le bloc de données lui-même.

Côté récepteur, on saura qu'au début de chaque nouveau bloc, on recevra d'abord sa taille sur 4 octets. Une fois la taille
reçue et décodée, on prépare un buffer de la bonne taille pour les données à recevoir. Tant que le buffer n'est pas rempli,
on ajoute tout ce qu'on reçoit dedans. Dès que le buffer est rempli, on sait qu'on a reçu un nouveau bloc de données.
On peut alors le traiter et recommencer à chercher à décoder la taille du bloc suivant.

lien : Pourquoi les nombres de paquets émis et reçus avec QTcpSocket diffèrent-il ?

- 159 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sommaire > QNetwork > Gestionnaire d'accès


Comment fonctionne le système de gestionnaire d'accès ?
Auteurs : Thibaut Cuvelier ,
Qt 4.4 nous fournit une alternative à QHttp et à QFtp : QNetworkAccessManager. Ce gestionnaire permet d'utiliser
d'autres protocoles (HTTPS, par exemple), sans devoir changer autre chose que les URL, dans son code.

L'architecture de ce nouveau système est tout à fait différente : il y a un objet-maître, un QNetworkAccessManager,


le gestionnaire. Il gère, entre autres, le cache, le proxy, les paramètres par défaut... C'est lui qui envoie les signaux de
fin de téléchargement, aussi.

On ne crée plus un objet indépendant par requête : on instancie un manager, puis on lui demande de récupérer un
fichier, grâce à son URL. Ce fichier est demandé sous la forme d'une requête QNetworkRequest. Cette requête ne
contient pas que l'URL : elle contient aussi les en-têtes supplémentaires à envoyer au serveur, la configuration SSL...

Une fois que le fichier a été téléchargé, il est renvoyé, sous la forme d'une réponse, un QNetworkReply. Il s'agit
d'un dérivé de QIODevice, et peut donc s'utiliser de la même manière. Il peut être envoyé en tant que paramètre du
signal finished() du gestionnaire, ou bien dès la demande du fichier (mais alors, il sera probablement vide, vu que le
gestionnaire n'aura sûrement pas le temps de commencer le téléchargement).

QNetworkAccessManager * manager = new QNetworkAccessManager();


QNetworkReply * reply = manager->get("http://qt.developpez.com");

Dès que le gestionnaire aura envoyé le signal finished(), la réponse contiendra le contenu du fichier.

Notez que l'on aurait pu aussi procéder de cette manière.

QNetworkAccessManager * manager = new QNetworkAccessManager();


manager->get("http://qt.developpez.com");

En effet, le gestionnaire enverra le signal finished() avec un argument, un pointeur vers la réponse.

Comment envoyer un fichier par le protocole HTTP ?


Auteurs : Thibaut Cuvelier ,
Le protocole HTTP est principalement prévu pour la récupération de données (par les méthodes GET et HEAD), mais
il peut aussi envoyer des données (par les méthodes POST et PUT). Il faut utiliser les méthodes du gestionnaire réseau
homonymes à la méthode.

Pour l'envoi, elles prennent deux paramètres : une requête QNetworkRequest et des données QByteArray.

QNetworkAccessManager * manager = new QNetworkAccessManager();

QUrl url ("<a href="http://qt.developpez.com" target="_blank">http://qt.developpez.com</a>");


QNetworkRequest request (url);
QByteArray data = "data";

- 160 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

manager->post(request, data);

Comment utiliser un proxy ?


Auteurs : Thibaut Cuvelier ,
Qt nous fournit une classe, QNetworkProxy, qui représente un proxy. Vous pouvez en spécifier un à votre gestionnaire
QNetworkAccessManager grâce à sa méthode setProxy(). Ce proxy peut être aussi utilisé par d'autres classes, plus
anciennes, à chaque fois grâce à la méthode setProxy() : QHttp, QFtp, QAbstractSocket, QTcpSocket, QUdpSocket,
QTcpServer...

Voici un exemple de création de proxy, assez explicite.

QNetworkProxy proxy;
proxy.setType(QNetworkProxy::Socks5Proxy);
proxy.setHostName("proxy.exemple.com");
proxy.setPort(1080);
proxy.setUser("username");
proxy.setPassword("password");

Le type du proxy est choisi dans l'énumération QNetworkProxy::ProxyType, que voici.

enum ProxyType { NoProxy, DefaultProxy, Socks5Proxy, HttpProxy,


HttpCachingProxy, FtpCachingProxy }

DefaultProxy oblige l'utilisation du proxy par défaut.

Maintenant, nous allons voir comment demander à un objet de passer par un proxy. Nous nous considérerons à la suite
de l'exemple de création d'un proxy.

QNetworkAccessManager manager ();


manager->setProxy (proxy);

QWebView * view = new QWebView () ;


view->page()->networkAccessManager()->setProxy(proxy);

lien : Comment définir un proxy par défaut ?

Comment définir un proxy par défaut ?


Auteurs : Thibaut Cuvelier ,
La fonction statique QNetworkProxy::setApplicationProxy() est utilisée pour définir le proxy par défaut de
l'application. Il sera utilisé par défaut dans l'application, mais il pourra être remplacé pour tous les objets en utilisant
d'autres méthodes.

On peut aussi récupérer ce proxy par défaut grâce à la fonction statique QNetworkProxy::applicationProxy().

// QNetworkProxy::applicationProxy() == QNetworkProxy()
QNetworkProxy::setApplicationProxy (proxy);

- 161 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

// QNetworkProxy::applicationProxy() == proxy

lien : Comment utiliser un proxy ?

Comment récupérer l'avancement du téléchargement ?


Auteurs : Jonathan Courtois ,
Le gestionnaire de requête QNetworkAccessManager permet de télécharger des fichiers à l'aide de la méthode get.

Il est également possible de suivre l'évolution du téléchargement pour, par exemple, l'afficher dans une barre de
progression. Il est nécessaire de connecter le signal downloadProgress à un slot à redéfinir.

QNetworkAccessManager * manager = new QNetworkAccessManager();


QNetworkReply * reply = manager->get("http://qt.nokia.com/logo.png");
connect(reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(requestDownloadProgress(qint64,
qint64)));

// Le slot de réception

void requestDownloadProgress(qint64 bytesReceived, qint64 bytesTotal)


{
qint64 pourcent = (bytesReceived / bytesTotal) * 100;
}

lien : Comment fonctionne le système de gestionnaire d'accès ?

Comment récupérer la source d'une page internet ?


Auteurs : Louis du Verdier ,
QtNetwork et QtWebkit sont deux modules permettant chacun de récupérer un fichier de l'Internet, comme des
pages web. QtNetwork fournit la classe QNetworkReply, que nous traiterons, et QtWebkit, QWebFrame. QHttp étant
obsolète, son cas ne sera pas traité ici.

Comme QNetworkReply hérite de QIODevice, il possède la fonction readAll(), qui permettra, dans l'exemple qui suit,
de récupérer ce qui est souhaité, balises HTML comprises :

QNetworkAccessManager *manager = new QNetworkAccessManager();


manager->get(QNetworkRequest(QUrl("http://qt.developpez.com/faq/")));
connect(manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(result(QNetworkReply *)));

void Classe::result(QNetworkReply *reply)


{
QString source = reply->readAll();
doSomething(source);
}

Cette solution ne prend pas en compte les redirections !

La seconde solution, avec QWebFrame, est très pratique car elle permet, en plus de gérer les redirections, de récupérer
la source de la page sous deux formats avec les fonctions toHtml(), qui retourne la source avec les balises HTML, et
toPlainText(), qui retourne la source sans les balises HTML.

view = new QWebView;


view->load(QUrl("http://qt.developpez.com/faq/"));
connect(view, SIGNAL(loadFinished(bool)), this, SLOT(result(bool)));

- 162 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

void Classe::result(bool)
{
QString html = view->page()->currentFrame()->toHtml();
QString plainText = view->page()->currentFrame()->toPlainText();
doSomething(html, plainText);
}

Si on décomposait le code de la fonction result(bool), située ci-dessus, on aurait ceci :

void Classe::result(bool)
{
QWebPage *page = view->page();
QWebFrame *frame = page->currentFrame();
QString html = frame->toHtml();
QString plainText = frame->toPlainText();
doSomething(html, plainText);
}

- 163 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sommaire > Phonon

- 164 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sommaire > Phonon > Généralités


Qu'est-ce que Phonon ?
Auteurs : LeGars ,
Phonon est un framework multimédia créé à l'origine pour le bureau KDE. Il offre des fonctions de base telles que la
lecture d'une vidéo ou d'un fichier son, le réglage du volume...

La particularité de Phonon réside dans le fait qu'il permet de s'abstraire des couches bas-niveau pour accéder aux
fonctions multmédia d'un système d'exploitation.

Ainsi, une application utilisant Phonon intégrera DirectX ou Xine/GStreamer ou QuickTime de façon transparente
pour le développeur. Chacun de ces accès étant géré par un plug-in nommé back-end. C'est ce dernier qui se chargera
d'intégrer la couche bas niveau dans l'application

Où récupérer Phonon ?
Auteurs : LeGars ,
Pour Windows et Mac OS, Phonon est directement inclus dans le framework Qt. Sous Linux, c'est généralement un
paquet à part.

Comment compiler Phonon pour Windows ?


Auteurs : LeGars ,
Avec Visual Studio Express.

1 Installer Visual Studio Express ;


2 Ouvrir la console via le raccourci de Visual Studio ;
3 Aller dans C:\qt\2009.03\qt (pour le Qt SDK ; dans les autres cas, aller dans le dossier des sources de Qt) ;
4 Taper configure.exe -phonon -platform win32-msvc2008 <autres...>
5 Taper nmake
6 Et c'est fini !

Avec MinGW.

1 Ouvrir la console via le raccourci du Qt SDK


2 Taper configure.exe -phonon <autres...>
3 Taper mingw32-make
4 Et c'est fini !

Comment intégrer Phonon dans un projet ?


Auteurs : LeGars ,
Contrairement aux autres classes de Qt, les noms de classes ne commencent pas par Q. C'est surtout dû au fait que
Phonon est un projet utilisant Qt, mais non de Qt.

Par exemple, pour ajouter la classe MediaSource, il faut ajouter cette ligne.

- 165 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

#include <Phonon/MediaSource>

Dans le fichier .pro

QT += phonon

- 166 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sommaire > Phonon > Backends


Qu'est ce qu'un back-end ?
Auteurs : LeGars ,
Un back-end est un plug-in pour phonon qui offre l'accès à une couche bas niveau spécifique. Par exemple, pour
Windows, il est possible d'utiliser le back-end DirectX. Le comportement est le suivant.

Application <-> Phonon <-> Backend DirectX <-> DirectX

Il existe aussi des back-end pour Mac (QuickTime) et Linux (Xine et GStreamer). Le développeur ne se concentre que
sur la communication entre son application et Phonon, permettant ainsi d'offrir une application réellement multi-
plateforme.

Quels sont les backend pour Windows ?


Auteurs : LeGars ,
Actuellement, il existe trois projets, avec divers états d'avancement.

• VLC : utilise la librairie libvlc du projet videolan, en cours de développement ;


• MPlayer : utilise le programme MPlayer, en cours de développement ;
• DirectX : fourni avec Qt.

- 167 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sommaire > Intégration avec d'autres librairies

- 168 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sommaire > Intégration avec d'autres librairies > boost.signals


Comment allier les signaux de Boost (boost.signals) aux signaux/slots de Qt ?
Auteurs : Denys Bulant ,
Il est intéressant de savoir faire ceci dans la mesure où vous désirez utiliser des classes écrites en C++ pur avec les
mécanismes Qt. Par exemple, une couche métier utilisant le mécanisme de boost.signals comme implémentation du
pattern observateur, que vous désirez connecter à la couche IHM écrite à l'aide de Qt.

Quelques considérations avant d'illustrer ceci.


• Si vous intégrez Qt et boost.signals dans un même fichier (requis pour permettre l'appel d'une fonction standard
depuis un signal Qt), il est impératif d'inclure les en-têtes boost en premier (sinon, vous obtiendrez un petit
paquet d'erreurs de compilation dues à Qt utilisant un #define sur signals).
• Mieux vaut le rappeler (et c'est d'autant plus vrai ici), si vous utilisez sender() dans un slot pour connaître
l'origine de l'appel, vérifiez toujours que le QObject* retourné est valide ! Bien sûr, il est de très loin préférable
de se passer de cette information, ce qui est la plupart du temps faisable.

Deux raisons à ce dernier point.


• Un slot peut être appelé comme une fonction normale (et, par conséquent, il n'y a d'objets appelant généré par
le système de méta-objets Qt).
• Un slot est appelé comme une fonction normale lors d'un appel par boost.signals (voir point précédent).

Maintenant, voilà les scénarios illustrés :


• Utilisation d'un boost.signal connecté à un slot Qt,
• Utilisation d'un boost.signal connecté à un signal Qt,
• Utilisation d'un signal Qt connecté à une (des) fonction(s) C++ standard par le biais de boost.signal.

Le code total et compilable sera présenté ; uniquement les snipets intéressants seront mis en avant lors de chaque
réponse.

lien : Comment utiliser un boost.signal connecté à un slot Qt ?


lien : Comment utiliser un boost.signal connecté à un signal Qt ?
lien : Comment utiliser un signal Qt connecté à une fonction standard par boost.signal ?

Comment utiliser un boost.signal connecté à un signal Qt ?


Auteurs : Denys Bulant ,
Un signal au sens Qt n'est qu'une méthode standard, le mot clé signals étant redéfini par Qt comme protected. Il est
donc nécessaire de fournir une méthode de déclencher ce signal avec le(s) paramètre(s) voulu(s). Il y a 2 approches
possible : la première consiste à ajouter une méthode à votre classe Qt, la seconde à utiliser une classe de pont.

Bien que plus verbeuse, la seconde méthode permet de découpler réellement la couche utilisant Qt de la couche sans
Qt en "intercalant" une couche servant d'aptateur.

Ici, ce sera la première méthode qui sera illustrée.

class QtClass : public QObject


{
Q_OBJECT

public:
QtClass()
{
connect(this, SIGNAL(qtSignal(float)), this, SLOT(qtSlot(float)));

- 169 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

// OBLIGATOIRE si on veut connecter un signal boost à un signal Qt : les signaux sont


**protégés**
void triggerQtSignalEmission(float x)
{
emit qtSignal(x);
}

signals:
void qtSignal(float);
};

class NonQtClass
{
public:
void boostSignalToQtSignal(QtClass *qc)
{
boost::signal<void (float)> sig;
sig.connect(boost::bind(&QtClass::triggerQtSignalEmission, qc, _1));
sig(42.0f);
}
};

Sortie obtenue
D'une connexion interne :
Dans QtClass::qtSlot(), x=42

lien : Comment allier les signaux de Boost (boost.signals) aux signaux/slots de Qt ?


lien : Comment utiliser un boost.signal connecté à un slot Qt ?
lien : Comment utiliser un signal Qt connecté à une fonction standard par boost.signal ?

Comment utiliser un boost.signal connecté à un slot Qt ?


Auteurs : Denys Bulant ,
Un slot au sens Qt est en réalité une fonction standard à laquelle peuvent être associées les informations de l'objet
appelant, si ledit slot est appelé depuis un signal Qt.

class QtClass : public QObject


{
Q_OBJECT
public slots: void qtSlot(float x)
{
QObject *s = sender();
if(s == this)
std::cout << "D'une connection interne :" << std::endl;
else if(!s)
std::cout << "Envoyeur inconnu :" << std::endl;
std::cout << "Dans QtClass::qtSlot(), x=" << x << std::endl;
}
};

class NonQtClass
{
public:
void boostSignalToQtSlot(QtClass *qc)
{
boost::signal<void (float)> sig;
sig.connect(boost::bind(&QtClass::qtSlot, qc, _1));
sig(3.14f);
}
};

- 170 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sortie obtenue
Envoyeur inconnu :
Dans QtClass::qtSlot(), x=3.14

lien : Comment allier les signaux de Boost (boost.signals) aux signaux/slots de Qt ?


lien : Comment utiliser un boost.signal connecté à un signal Qt ?
lien : Comment utiliser un signal Qt connecté à une fonction standard par boost.signal ?

Comment utiliser un signal Qt connecté à une fonction standard par boost.signal ?


Auteurs : Denys Bulant ,
Ici, ça se complique un peu. En effet, nous savons :
• Qu'un signal Qt est une méthode protégée ;
• Que le corps d'un signal Qt va associer les informations sur l'objet émetteur (dans le but de permettre
l'utilisation de la méthode sender() dans le slot) ;
• Que nous ne pouvons passer de fonctions standard à un signal Qt.

Nous allons donc mettre en place ici une méthode impliquant la création d'une classe servant d'adaptateur entre les
deux paradigmes (signaux Qt / boost.signals).

class QtClass : public QObject


{
Q_OBJECT

public:
// OBLIGATOIRE si on veut connecter un signal boost à un signal Qt: les signaux sont
**protégés**
void triggerQtSignalEmission(float x)
{
emit qtSignal(x);
}

signals:
void qtSignal(float);
};

class QtSignalToStandardCPPBridge : public QObject


{
Q_OBJECT

public:
QtSignalToStandardCPPBridge(QtClass *qc)
{
connect(qc, SIGNAL(qtSignal(float)), this, SLOT(onQtSignalEmitted(float)));
}

template<typename Signature>
void addStandardSlot(Signature fun)
{
sig.connect(fun);
}

private slots:
void onQtSignalEmitted(float x)
{
sig(x);
}

private:
boost::signal<void (float)>sig;
};

- 171 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

class NonQtClass
{
public:
// fonction normale que l'on appelera depuis un signal Qt en passant par un pont
void normalFunction(float x)
{
std::cout << "Dans NonQtClass::normalFunction(), x=" << x << std::endl;
}

// Et une autre pour le fun


void displaySquareRoot(float x)
{
std::cout << "Dans NonQtClass::displaySquareRoot(), sqrt(x)=" << std::sqrt(x) << std::endl;
}

public:
void QtSignalToStandardFunction(QtClass *qc)
{
QtSignalToStandardCPPBridge adapter(qc);
adapter.addStandardSlot(boost::bind(&NonQtClass::normalFunction, this, _1));
adapter.addStandardSlot(boost::bind(&NonQtClass::displaySquareRoot, this, _1));
// On déclenche ici manuellement l'émission du signal Qt
qc->triggerQtSignalEmission(121.0f);
}
};

Sortie obtenue
Dans NonQtClass::normalFunction(), x=121
Dans NonQtClass::displaySquareRoot(), sqrt(x)=11

lien : Comment allier les signaux de Boost (boost.signals) aux signaux/slots de Qt ?


lien : Comment utiliser un boost.signal connecté à un slot Qt ?
lien : Comment utiliser un boost.signal connecté à un signal Qt ?

- 172 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sommaire > EDI


Comment utiliser NetBeans avec Qt ?
Auteurs : Thibaut Cuvelier ,
Suivez ces quelques étapes pour pouvoir utiliser NetBeans avec Qt.

• Installez NetBeans.
• Installez MinGW, MSYS et la dernière version de Qt (compilée pour MinGW) ; ou bien le Qt SDK.
• Ajoutez le répertoire de qmake (Qt/bin) à votre PATH.
• Dans NetBeans, ajoutez les différents chemins qui correspondent à votre compilateur (Tools > Options > C/C+
+).

- 173 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sommaire > EDI > QtCreator


Qu'est-ce que Qt Creator ?
Auteurs : Jonathan Courtois ,
Qt Creator est un environnement de développement intégré (IDE) réalisé par Nokia. Il facilite la gestion d'un projet
Qt grâce à un éditeur de texte reconnaissant la syntaxe Qt, ce qui permet la coloration syntaxique, la complétition,
l'indentation, etc. Il est cependant également utilisable pour des projets n'utilisant pas le framework Qt. Qt Creator
intègre en son sein les outils Qt Designer et Qt Assistant. Il fait partie du SDK de Qt depuis la version 4.5, mais est
également disponible en stand-alone, sans Qt d'installé.

Qt Creator n'est pas :


• Un compilateur, il peut cependant en utiliser un grand nombre, comme GCC ou Visual C++ ;
• Un débogueur, il propose cependant une interface de débogage intuitive et spécialisée pour Qt permettant
d'utiliser GDB (GCC) ou CDB (Visual C++) ;
• Un outil de compilation, il utilise par défaut QMake mais peut également utiliser CMake ou d'autres outils.

Il est construit sur la base de plug-ins permettant d'ajouter des fonctionnalités facilement, étant donné qu'il est open
source.

Comment utiliser QtCreator avec les outils de Visual Studio (compilateur et débogueur) ?
Auteurs : Thibaut Cuvelier ,
Il vous suffit d'avoir à disposition quelques outils, et de configurer légèrement Qt Creator.

• Installez Visual Studio si ce n'est déjà fait.


• Compilez Qt pour Visual Studio ou récupérez un de nos paquets de Qt précompilé pour Visual Studio.

Installez les Microsoft Debugging Tools.
• Installez Qt Creator (au moins en version 1.2).
• Dans Tools < Options, vérifiez que Qt Creator trouve la version de Qt compilée pour Visual Studio, et qu'elle est
utilisée par défaut.
Cochez la case en face de cdb. S'il n'est pas trouvé, indiquez le chemin.
Si Debugging Helper est marqué d'une croix rouge, cliquez sur le bouton Rebuild.

Quels sont les plugins actuellement disponibles ?


Auteurs : Jonathan Courtois ,
Qt Creator est construit sur la base de plug-ins permettant d'ajouter facilement des fonctionnalités sans modifier
l'intégralité du code de l'IDE, favorisant ainsi le développement collaboratif. L'ensemble des plug-ins actuellement
disponibles (version 1.2.0) est entièrement réalisé par Nokia.

Gestion de configuration : Subversion, ScmGit, Perforce, VCSBase.


Gestion des sources des projets avec un gestionnaire de configuration.

Outils de compilation : CMakeProjectManager, GenericProjectManager. Compilatio de projets avec d'autres outils que
QMake.

Editeurs de fichiers : BinEditor, CppEditor, QtScriptEditor, ResourceEditor, TextEditor.


Édition des fichiers avec des interfaces spécifiques.

- 174 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Intégration d'outils : Designer, Help.


Intégration d'outils déjà existant à Qt Creator (Qt Designer, documentation#).

Divers : Debugger, Bookmarks, QuickOpen, CodePaster, FakeVim, Find, CppTools, Qt4ProjectManager, Core#

Comment garder ses projets dans Qt Creator ?


Auteurs : Jonathan Courtois ,
Pour conserver l'ensemble de ses projets ouverts entre deux instances de Qt Creator, il a été mis en place la notion de
Session par l'équipe Qt by Nokia.

Une session est créée par défaut et vous permettra en l'ouvrant de récupérer les projets de votre dernière instance. Il
est également possible de créer ses propres sessions grâce au session manager permettant de gérer différents espaces
de travail.

Pour terminer, les sessions sont à voir comme une sauvegarde d'un environnement de travail incluant plusieurs projets :
aucune option de configuration n'est liée à celle-ci.

- 175 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sommaire > Les bibliothèques complémentaires


Comment gérer le port série ?
Auteurs : Matthieu Brucher ,
Qt ne gère pas de manière native le port série. En revanche, des projets externes existent, en particulier QExtSerialPort.

lien : Le site officiel de QExtSerialPort

- 176 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sommaire > Les bibliothèques complémentaires > Qwt


Qu'est ce que Qwt ?
Auteurs : gulish ,
Qwt (Qt Widgets for Technical Applications) est une librairie annexe à Qt, qui utilise cette dernière, et qui simplifie la
création de widgets de mesure (courbes, graphiques, jauges, cadrans...). Cette librairie, ainsi que toutes les informations
la concernant, sont disponibles sur la page web du projet.

lien : Qwt

Quels types de composants puis je créer avec Qwt ?


Auteurs : gulish ,
Quelques images des exemples Qwt sont disponibles dans le chapitre "Screenshots" de la page web de la librairie. Elles
sont assez représentatives du type de composants pouvant être créés, même si une personnalisation est toujours possible.

lien : Qwt

Est il difficile d'utiliser Qwt ?


Auteurs : gulish ,
Les classes Qwt sont basées sur celles de Qt, et leur utilisation est relativement simple. De plus, les classes disponibles sont
assez complètes, et permettent facilement de créer l'objet que l'on désire. Cependant, cette librairie est moins intuitive
que Qt, et la documentation la concernant est plutôt succinte. Il est nécessaire de connaître les bases de l'utilisation de
Qt pour utiliser Qwt.

Comment installer Qwt ?


Auteurs : gulish ,
Qwt est basé sur Qt, et il faut donc préalablement avoir installé la librairie Qt. Il suffit ensuite de décompresser l'archive
Qwt, modifier le fichier .pri (similaire au fichier .pro) selon vos besoins, puis d'exécuter qmake, puis make ou équivalents
(nmake, cmake...).

Comment insérer un composant Qwt dans mon application Qt ?


Auteurs : gulish ,
Les repères des courbes (QwtPlot) et les éléments de type "jauges" (QwtCompass, QwtDial, QwtKnob...) héritent tous
de la classe QWidget. Il est donc facile de les ajouter, comme tout autre widget, dans le layout de votre application.

Comment créer un repère dans mon interface ?


Auteurs : gulish ,
La classe principale pour la gestion des repères est QwtPlot. Son utilisation est très simple. Par défaut, seule la partie
positive des axes x et y apparaît, mais cela est modifiable.

- 177 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

#include <QApplication>
#include <qwt_plot.h>

int main(int argc, char** argv)


{
QApplication app(argc,argv);
QwtPlot myPlot;
myPlot.show();
return app.exec();
}

Comment changer la couleur de fond de mon repère ?


Auteurs : gulish ,
On utilise la méthode setCanvasBackground (const QColor &c).

#include <QApplication>
#include <qwt_plot.h>

int main(int argc, char** argv)


{
QApplication app(argc,argv);
QwtPlot myPlot;
myPlot.setCanvasBackground(Qt::white);
myPlot.show();
return app.exec();
}

Comment ajouter une courbe sur mon repère ?


Auteurs : gulish ,
Les courbes se créent grâce à la classe QwtPlotCurve. Cette classe permet une grande personnalisation de l'affichage
(symboles des points, couleur, traçage ou non de ligne, etc.). Une courbe étant une suite de points, il faut renseigner une
suite de points à QwtPlotCurve. Pour cela, on utilise la méthode setData(...), qui peut accepter différents arguments.
La plus triviale est setData (const double *xData, const double *yData, int size), où xData représente un tableau de
double, contenant toutes les abscisses des points de notre courbe, yData contient, lui, les ordonnées. Ainsi, notre premier
point aura comme coordonnées [ xData[0],yData[0] ]. Le troisième paramètre, size, renseigne sur le nombre de points
à afficher, en partant de zéro. Bien sûr, xData et yData doivent au moins contenir size éléments.

#include <QApplication>
#include <qwt_plot.h>
#include <qwt_plot_curve.h>

int main(int argc, char** argv)


{
QApplication app(argc,argv);
QwtPlot myPlot;
QwtPlotCurve myCurve;

// indique à myPlot qu'il doit afficher myCurve


myCurve.attach(&myPlot);

// QVector peut être facilement manipulé, et peut être convertit en double[];


QVector<double> x(5);
QVector<double> y(5);
// On entre des valeurs
for(int i=0;i<5;i++)
{

- 178 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

x.append((double)i);
y.append((double)(5-i));
}
myCurve.setData(x.data(),y.data(),x.size());

// Il faut rafraîchir l'affichage grâce à la méthode replot(), quand les données ont changé.
myPlot.replot();
myPlot.show();
return app.exec();
}

Vous remarquerez que les axes se sont automatiquement ajustés aux données.

Comment changer la couleur de ma courbe ?


Auteurs : gulish ,
Il faut utiliser la méthode QwtPlotCurve::setPen().

#include <QApplication>
#include <qwt_plot.h>
#include <qwt_plot_curve.h>

int main(int argc, char** argv)


{
QApplication app(argc,argv);
QwtPlot myPlot;
QwtPlotCurve myCurve;
// indique à myPlot qu'il doit afficher myCurve
myCurve.attach(&myPlot);

// QVector peut être facilement manipulé, et peut être convertit en double[];


QVector<double> x(5);
QVector<double> y(5);
// On entre des valeurs
for(int i=0;i<5;i++)
{
x.append((double)i);
y.append((double)(5-i));
}
myCurve.setData(x.data(),y.data(),x.size());
// courbe en rouge
myCurve.setPen(QPen(Qt::red));
// Il faut rafraîchir l'affichage grâce à la méthode replot(), quand les données ont changé.
myPlot.replot();
myPlot.show();
return app.exec();
}

Comment ajouter une grille à mon repère ?


Auteurs : gulish ,
Il est inutile d'ajouter une multitude de courbes pour faire apparaître une grille sur notre repère. QwtPlotGrid permet
d'ajouter facilement une grille à notre repère. De plus, cette grille s'adapte automatiquement aux nouvelles échelles,
et peut être personnalisée.

#include <QApplication>
#include <qwt_plot.h>
#include <qwt_plot_curve.h>

- 179 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

#include <qwt_plot_grid.h>

int main(int argc, char** argv)


{
QApplication app(argc,argv);
QwtPlot myPlot;
QwtPlotCurve myCurve;
QwtPlotGrid myGrid;
// indique à myPlot qu'il doit afficher myCurve
myCurve.attach(&myPlot);

// QVector peut être facilement manipulé, et peut être convertit en double[];


QVector<double> x(5);
QVector<double> y(5);

// On entre des valeurs


for(int i=0;i<5;i++)
{
x.append((double)i);
y.append((double)(5-i));
}

myCurve.setData(x.data(),y.data(),x.size());

// indique à myPlot qu'il doit afficher myGrid


myGrid.attach(&myPlot);

// Il faut rafraîchir l'affichage grâce à la méthode replot(), quand les données ont changé.
myPlot.replot();
myPlot.show();
return app.exec();
}

Comment ajouter des grilles seulement horizontales/verticales ?


Auteurs : gulish ,
On peut facilement réaliser ce type de grille grâce aux méthodes QwtPlotGrid::enableX() et QwtPlotGrid::enableY().

#include <Application>
#include <QHBoxLayout>
#include <qwt_plot.h>
#include <qwt_plot_curve.h>
#include <qwt_plot_grid.h>

int main(int argc, char** argv)


{
QApplication app(argc,argv);
QWidget myWidget;

QwtPlot myLeftPlot;
QwtPlotGrid myLeftGrid;
myLeftGrid.enableX(false); // On affiche seulement les lignes horizontales
myLeftGrid.attach(&myLeftPlot);

QwtPlot myRightPlot;
QwtPlotGrid myRightGrid;
myRightGrid.enableY(false); // On affiche seulement les lignes verticales
myRightGrid.attach(&myRightPlot);

QHBoxLayout myLayout(&myWidget);
myWidget.setLayout(&myLayout);
myLayout.addWidget(&myLeftPlot);
myLayout.addWidget(&myRightPlot);

- 180 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

myLeftPlot.replot();
myRightPlot.replot();
myWidget.show();
return app.exec();
}

Comment spécifier des valeurs à mes axes ?


Auteurs : gulish ,
Les axes peuvent simplement se personnaliser grâce aux fonctions setAxisScale (axe,min,max,step) et setAxisTitle
(axe,titre). Dans la majorité des cas, la grille s'ajuste automatique sur l'échelle du repère.

#include <QApplication>
#include <qwt_plot.h>
#include <qwt_plot_curve.h>
#include <qwt_plot_grid.h>

int main(int argc, char** argv)


{
QApplication app(argc,argv);

QwtPlot myPlot;
QwtPlotGrid myGrid;
myGrid.attach(&myPlot);

// l'axe x ira de -15 à +35, en affichant les valeurs de 5 en 5


myPlot.setAxisScale(QwtPlot::xBottom,-15.0,35.0,5.0);
myPlot.setAxisScale(QwtPlot::yLeft,-70.0,-35.0,5.0);

myPlot.setAxisTitle(QwtPlot::xBottom,QString("My x values"));
// On peut bien sûr utiliser les mêmes propriétés que QString
myPlot.setAxisTitle(QwtPlot::yLeft,QString("<u>My y values</u>"));

myPlot.replot();
myPlot.show();

return app.exec();
}

Comment ajouter un outil de zoom sur mon repère ?


Auteurs : gulish ,
Il existe une classe dédiée au zoom nommée QwtPlotZoomer. Elle permet de créer très simplement un outil de zoom, et
d'autres fonctionnalités. On peut zoomer successivement sur une zone. Le zoom s'effectue en faisant un cliquer-glisser
sur une zone du repère, le clic sur la molette permet de revenir au zoom précédent, et le clic droit permet de revenir
au repère initial. La grille et les axes s'ajustent avec le zoom.

#include <QApplication>
#include <qwt_plot.h>
#include <qwt_plot_curve.h>
#include <qwt_plot_grid.h>
#include <qwt_plot_zoomer.h>
int main(int argc, char** argv)
{
QApplication app(argc,argv);

QwtPlot myPlot;
QwtPlotGrid myGrid;

- 181 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

myGrid.attach(&myPlot);
QwtPlotZoomer myZoomer(myPlot.canvas());

myPlot.replot();
myPlot.show();

return app.exec();
}

- 182 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Sommaire > Les bibliothèques complémentaires > QCA


Qu'est-ce que QCA ?
Auteurs : Thibaut Cuvelier ,
QCA (Qt Cryptographic Architecture) est une librairie annexe à Qt. Elle fournit des services cryptographiques pour Qt,
qui ne gère nativement que les hash MD4, MD5 et SHA1. Les dernières versions sont compatibles avec Qt3 et Qt4.

Toutes les fonctionnalités cryptographiques sont fournies par des plug-ins (dans le dossier plugins/crypto), chargés
dynamiquement, à l'exécution, en fonction des besoins.

Cette librairie est orientée vers la sécurité : outre les hash (MD4, MD5, SHA-1, SHA-512, Blowfish...), elle propose une
implémentation des algorithmes les plus répandus et éprouvés (TLS, OpenGPG, RSA...), des emplacements mémoires
sécurisés (qui ne seront jamais écrits sur le disque dur), des nombres pseudo-aléatoires...

QCA se base sur un système de plug-ins : lui-même ne fournit strictement rien, tout est implémenté dans les plug-ins.
Ces plug-ins se servent d'autres bibliothèques renommées et optimisées : OpenSSL, Cyrus SASL, GNU PG...

Comment installer QCA ?


Auteurs : Thibaut Cuvelier ,
Il y a deux possiblités : soit les binaires pour votre compilateur sont déjà disponibles, soit ils ne le sont pas. S'ils le sont,
téléchargez cette archive et installez-la. Sous Windows, n'oubliez pas d'exécuter le script installwin.bat : il installera
les fichiers nécessaires dans votre installation de Qt. S'ils ne le sont pas, suivez cette marche à suivre. N'oubliez surtout
pas de télécharger les plug-ins !

Vous devez commencer par récupérer les sources sur le site officiel. Elles sont compressées avec BZip2 et rassemblées
avec TAR : vous pouvez utiliser ces binaires en ligne de commande, ou utiliser un archiveur comme 7Zip ou WinRar.

Dans un invite de commandes, entrez ceci pour Windows et Visual Studio.

configure
nmake
installwin

Ceci pour Windows et MinGW/GCC.

configure
make
installwin

Ceci pour les autres systèmes d'exploitation.

./configure
make
make install
/sbin/ldconfig

Ensuite, configurez votre IDE avec les répertoires de QCA (répertoires include/, lib/ et bin/).

Ici, vous n'aurez que QCA, sans le moindre plug-in, c'est-à-dire une carcasse sans chair.

- 183 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

Vous devrez télécharger les sources de chaque plug-in ainsi que les dépendances. Les fichiers de projet sont livrés.
Utilisez simplement ces commandes (pour Visual Studio).

qmake
nmake

Ou bien celles-ci (pour les autres compilateurs).

qmake
make

Comment compiler une application avec QCA ?


Auteurs : Thibaut Cuvelier ,
Il vous suffit de vous assurer que votre application liera bien avec libqca.

Vous devez toujours passer par qmake, comme d'habitude avec Qt. Cependant, vous devrez utiliser une nouvelle ligne
dans votre fichier de projet. La voici.

CONFIG *= crypto

Si vous voulez générer un nouveau projet, et que cette ligne soit déjà incluse, vous pouvez utiliser cette commande.

qmake -project "CONFIG *= crypto

Ici, l'opérande *= permet de n'inclure la librairie que si elle ne l'est pas encore, contrairement
à +=, qui ajoute inconditionnellement.

Comment générer un nombre pseudo-aléatoire ?


Auteurs : Thibaut Cuvelier ,
QCA fournit la classe QCA::Random pour la génération de nombres pseudo-aléatoires. Seules ses fonctions statiques
sont prévues pour être utilisées. Les voici.

• randomChar() (renvoie un unsigned char),


• randomInt() (renvoie un int),
• randomArray() (renvoie un QCA::SecureArray).

Les nombres sont générés à partir d'un plug-in. Ceci signifie que le plug-in définit les bornes des nombres générés,
vous ne pouvez pas le spécifier, contrairement à Boost.Random (dans Boost, vous choisissez la fonction ; dans QCA,
un plug-in est choisi).

// On initialise QCA, ce qui permettra de nettoyer la mémoire


// en fin de programme
QCA::Initializer init;

// Un entier pseudo-aléatoire
int randInt = QCA::Random::randomInt();

// Un caractère (octet) pseudo-aléatoire


unsigned char randInt = QCA::Random::randomChar();

- 184 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

// 10 octets aléatoires
// Un octet est un nombre compris entre (2^0)-1 et (2^8)-1
// c'est-à-dire entre 0 et 255
QCA::SecureArray array = QCA::Random::randomArray(10);

lien : Pourquoi parler de nombres pseudo-aléatoires ?

Pourquoi parler de nombres pseudo-aléatoires ?


Auteurs : Thibaut Cuvelier ,
Un ordinateur est incapable de décider arbitrairement d'un nombre, il doit se baser sur un élément, de préférence
variable dans le temps. En général, il s'agit du timestamp. Les algorithmes de génération de nombre pseudo-aléatoires
sont chaotiques, c'est-à-dire que, pour une très petite variation de l'entrée, le résultat est fort différent.

Le problème, c'est que, si l'on prend beaucoup de nombres générés, et que l'on divise la borne en quatre, chaque quart
aura le même nombre de nombres générés : ils seront également répartis entre ces quatre quarts.

lien : Comment générer un nombre pseudo-aléatoire ?

Comment générer un hash cryptographique de données ?


Auteurs : Thibaut Cuvelier ,
QCA, en tant que librairie de cryptographie, propose des primitives cryptographiques, comme des algorithmes de hash.

Un hash est une empreinte qui permet d'identifier, avec un certain degré d'erreur, des données. Plusieurs données
peuvent avoir le même hash : cela s'appelle une collision. Ce sont ces collisions qui mettent à mal certains anciens
algorithmes (MD4, MD5, SHA-0, bientôt SHA-1) : en effet, cela permet d'envoyer un fichier corrompu et vérolé
sans que le destinataire ne puisse le remarquer.

QCA supporte un certain nombre d'algorithmes de hashage.

• SHA-0,
• SHA-1,
• MD2,
• MD4,
• MD5,
• RIPEMD160,
• SHA-224,
• SHA-256,
• SHA-384,
• SHA-512,
• Whirlpool.

Pour pouvoir hasher des données, il faut commencer par initialiser un QCA::Hash avec un des algorithmes ci-dessus
(écrivez le nom de l'algorithme en minuscules, en gardant tiret et chiffres). Ensuite, vous utilisez la fonction update()
pour y insérer des données. final() permet de récupérer le hash résultant.

Cependant, avant de pouvoir utiliser un algorithme de hash, vous devez être sûr qu'il soit disponible. En effet, tous les
algorithmes de hash sont implémentés dans des plug-ins. Pour ce faire, utilisez la fonction QCA::isSupported().

Voici un exemple d'utilisation, avec stockage du hash en mémoire sécurisée.

- 185 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

#include <QtCrypto>
int main(){

// Création du tableau qui recevra le hash


QCA::SecureArray hash;
// Instanciation du hasher
QCA::Hash hasher ("sha1");

// Le plug-in de SHA-1 a-t-il été chargé ?


if( QCA::isSupported("sha1") )
{
// On ajoute la chaîne "password" aux données à hasher
hasher.update ( "password" );
// On ajoute le QByteArray "salt" aux données à hasher
hasher.update ( QByteArray ("salt") );
// On ajoute le contenu du fichier "salts.sha1" aux données à hasher
hasher.update ( QFile ("salts.sha1") );
// On écrit dans le tableau le hash
hash = hasher.final();
}

// Le plug-in de Whirlpool a-t-il été chargé ?


if( QCA::isSupported("whirlpool") )
{
// On ajoute la chaîne "password" aux données à hasher
hasher.update ( "password" );
// On ajoute le QByteArray "salt" aux données à hasher
hasher.update ( QByteArray ("salt") );
// On ajoute le contenu du fichier "salts.whirl" aux données à hasher
hasher.update ( QFile ("salts.whirl") );
// On écrit dans le tableau le hash
hash = hasher.final();
}

Comment utiliser la mémoire sécurisée ?


Auteurs : Thibaut Cuvelier ,
QCA fournit la classe SecureArray pour gérer la mémoire sécurisée. Elle se différencie de QString ou de QByteArray
par le fait que l'on peut être sûr que les données seront écrites uniquement en mémoire vive, jamais sur le disque dur,
où elles pourraient être récupérées facilement.

Elle est semblable à QByteArray pour les fonctionnalités proposées : append(), at(), clear(), constData(), data(), resize()
et size() sont autant de fonctions qui existent des deux côtés. Un SecureArray peut être facilement transformé en
QByteArray grâce à la fonction toByteArray().

Cette classe est implicitement partagée (elle dérive de QSharedDataPointer).

Voici un exemple d'utilisation : un calcul de hash puis stockage en mémoire sécurisée.

#include <QtCrypto>
int main(){

// Création du tableau qui recevra le hash


QCA::SecureArray hash;

- 186 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/
La FAQ Qt

// Le plug-in de SHA-1 a-t-il été chargé ?


if( QCA::isSupported("sha1") )
{
// Instanciation du hasher
QCA::Hash hasher ("sha1");
// On ajoute la chaîne "password" aux données à hasher
hasher.update ( "password" );
// On écrit dans le tableau le hash
hash = hasher.final();
}

lien : Comment générer un hash cryptographique de données ?

- 187 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006 - 2010 Developpez LLC. Tout droits réservés Developpez LLC. Aucune
reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez
LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://qt.developpez.com/faq/

Você também pode gostar