summaryrefslogtreecommitdiffstats
path: root/doc/fr/PerlQt.pod
diff options
context:
space:
mode:
Diffstat (limited to 'doc/fr/PerlQt.pod')
-rw-r--r--doc/fr/PerlQt.pod1189
1 files changed, 1189 insertions, 0 deletions
diff --git a/doc/fr/PerlQt.pod b/doc/fr/PerlQt.pod
new file mode 100644
index 0000000..5036239
--- /dev/null
+++ b/doc/fr/PerlQt.pod
@@ -0,0 +1,1189 @@
+
+=head1 Programmer avec PerlQt
+
+B<Germain Garand> traduit par B<Stéphane Payrard>, révisé et augmenté par l'auteur.
+
+Ce document décrit l'interface Perl au toolkit Qt 3.x. Contacter
+l'auteur à <germain@ebooksfrance.com> ou le traducteur à
+<stef@mongueurs.net>. Vous trouverez le document original sur le site
+L<perlqt.sourceforge.net|"http://perlqt.sourceforge.net">
+
+=head1 Introduction
+
+PerlQt-3, crée par Ashley Winters, est une interface perl aux composants
+graphiques (et non graphiques) fournis par Qt3.
+
+Le toolkit Qt 3.0 auquel PerlQt accède à été écrit en C++ par la société
+Trolltech: L<Trolltech|"http://www.trolltech.com">.
+
+PerlQt3 est fondé sur la librairie
+L<SMOKE|"http://webcvs.kde.org/cgi-bin/cvsweb.cgi/kdebindings/smoke">,
+une surcouche fine indépendante du langage. Cette couche a été générée
+à partir des fichiers d'en tête de Qt par le
+L<kalyptus|"http://webcvs.kde.org/cgi-bin/cvsweb.cgi/kdebindings/kalyptus">
+de Richard Dale grâce au module de David Faure.
+
+Le présent document décrit les principes de la programmation PerlQt.
+Vous devez avoir des notions de programmation orientée objet en Perl pour le
+lire. Une connaissance de C++ est recommandée mais non requise. Avec
+celle de l'anglais, elle vous facilitera la consultation des L<manuels
+en ligne de Qt|"http://doc.trolltech.com">. Ladite documentation est
+la seule référence qui fasse autorité.
+
+Si Qt est installé sur votre système, sa documentation l'est
+certainement aussi : voyez le programme $QTDIR/bin/assistant.
+
+=head1 Installation
+
+=head2 Conditions requises
+
+Pour compiler et utiliser PerlQt, vous devez avoir:
+
+
+=over 4
+
+=item *
+
+un système conforme à la norme POSIX.
+
+=item *
+
+L<Perl E<gt>= v5.6.0|"http://www.perl.org">
+
+=item *
+
+L<Qt E<gt>=
+v3.0|"http://www.trolltech.com/developer/download/qt-x11.html">
+
+=item *
+
+L<SmokeQt
+1.2.1|"http://webcvs.kde.org/cgi-bin/cvsweb.cgi/kdebindings/smoke"> La
+librarie SMOKE (Scripting Meta Object Kompiler) fait partie du module
+L<KDE|"http://www.kde.org">'s B<kdebindings>. Vous pouvez vérifier si
+une version précompilée de ce module existe pour votre système. Mais
+perlQt inclut une copie, donc la version précompilée n'est pas
+nécessaire.
+
+=item *
+
+Les outils GNU : automake(>=1.5), autoconf (>=2.13), aclocal...
+
+=back
+
+L'installation de Perl et de Qt sont en dehors du sujet du présent
+document. Se référer aux documentations respectives de ces logiciels.
+
+=head2 Compilation de PerlQt
+
+Les instructions de cette section présupposent que le répertoire courant est
+le répertoire racine de l'arborescence des sources de PerlQt.
+
+PerlQt utilise le système GNU Autoconf, mais il est préférable de le lancer via
+le script standard C<Makefile.PL> :
+
+ perl Makefile.PL
+
+B<N.B :> Si la variable d'environnement B<QTDIR> n'est pas définie, vous devrez
+peut-être spécifier manuellement l'emplacement de Qt à l'aide de l'option :
+
+ --with-qtdir=/emplacement/de/Qt
+
+Si la bibliothèque SMOKE est manquante, C<configure> générera ses sources dans
+un sous-répertoire.
+
+ make
+
+ make install
+
+Cela installera PerlQt, Puic et les utilitaires pqtsh et pqtapi.
+
+Le lieu d'installation privilégié de SMOKE et de PUIC est le système de
+fichiers de KDE3. Si KDE3 n'est pas installé (ou que la variable KDEDIR n'est pas
+définie), spécifier ce lieu avec l'option C<--prefix> de C<configure>'s. Ainsi :
+
+ perl Makefile.PL --prefix=/usr
+
+=head2 Installation avec les droits d'utilisateur
+
+Pour réaliser une installation locale, sans les droits de super-utilisateur,
+suivez les instructions suivantes :
+
+=over 4
+
+=item *
+
+Réalisez tout d'abord une configuration normale, en spécifiant le préfixe de la hiérarchie de fichier
+dans laquelle la bibliothèque Smoke et l'exécutable 'puic' seront installés :
+
+ perl Makefile.PL --prefix=~
+
+Ceci installera Smoke dans ~/lib et puic dans ~/bin
+
+=item *
+
+Reconfigurez le module PerlQt pour qu'il ne s'installe pas dans la hiérarchie Perl ordinaire :
+
+ cd PerlQt
+ perl Makefile.PL PREFIX=~
+ cd ..
+
+Attention : il ne s'agit pas du Makefile.PL situé à la racine de l'arborescence mais bien de celui
+situé dans le sous-répertoire PerlQt
+
+=item *
+
+Lancez la compilation et l'installation
+
+ make && make install
+
+Pour exécuter des programmes PerlQt, il vous faudra désormais indiquer à Perl l'emplacement de cette hiérarchie externe,
+à l'aide d'une ligne de la forme :
+
+ perl -Mlib="~/local/lib/perl/5.x.x" programme.pl
+
+où 5.x.x représente la version de Perl utilisée, ligne qui peut également être placée en tête de programme :
+
+ use lib qw( ~/local/lib/perl/5.x.x );
+
+=back
+
+=head1 Anatomie de PerlQt
+
+Un programme Qt typique utilisant des composants GUI est fondé sur une
+boucle événementielle.
+
+Il ne se comporte pas comme une suite séquentielle
+d'instructions où vous devriez gérer vous-même chaque événement (tels
+que le clic de la souris ou l'enfoncement d'une touche).
+
+Au lieu de cela, vous créez un objet B<Qt::Application> et les composants
+du GUI qu'il utilise, puis vous définissez les méthodes d'objet à appeler
+lors de l'occurrence d'un événement, puis démarrez la boucle événementielle.
+
+C'est tout. Qt gérera les événements et les dirigera vers les
+routines appropriées.
+
+Voyons un programme PerlQt minimal.
+
+=head2 Hello World
+
+ 1: use Qt;
+ 2: my $a = Qt::Application(\@ARGV);
+ 3: my $hello = Qt::PushButton("Hello World!", undef);
+ 4: $hello->resize(160, 25);
+ 5: $a->setMainWidget($hello);
+ 6: $hello->show;
+ 7: exit $a->exec;
+
+=for html
+<br/>
+<div class='image'><img src="../images/ex1.png"/></div>
+
+Ce programme charge d'abord le module Qt [line 1] puis crée l'objet
+application B<$a> en lui passant une référence au tableau C<@ARGV>
+contenant les arguments de la ligne de commande [l.2]. Cet objet
+application est unique pour un interpréteur Perl donné et peut être
+ensuite accédé par la fonction pure B<Qt::app()>.
+
+La ligne 3, crée un PushButton orphelin (c.à.d sans parent: non
+contenu dans un autre widget) dont nous passons la valeur B<undef>
+comme argument pour le parent. B<undef> est l'équivalent perlQt d'un
+pointeur null en C++.
+
+Après les instructions de "mise en page" [l.4], nous indiquons à
+l'objet application que le widget principal est ce
+PushButton... Ainsi, il saura que fermer la fenêtre associée à ce
+widget signifie: I<sortir de l'application>.
+
+Pour rendre ce widget visible (qui est par défaut caché), on
+appelle la méthode B<show> [l.6] et lance la boucle
+événementielle [l.7].
+
+B<Sommaire de la syntaxe :>
+
+=over 4
+
+=item 1
+
+Les classes PerlQt sont accessibles par le préfixe B<Qt::> au lieu du
+B<Q> initial des classes Qt en C++. En consultant la L<documentation
+Qt|"http://doc.trolltech.com">, vous devez donc mentalement changer le
+nom d'une clasee B<QFoo> en B<Qt::Foo>.
+
+=item 2
+
+De manière similaire à C++, un objet est créé par l'appel d'un
+B<constructeur> de même nom que la classe dont il est une méthode.
+
+Vous ne devez donc pas dire C<new Qt::Foo> ou C<Qt::Foo-E<gt>new()>
+contrairement à l'usage commun en Perl.
+
+Dites simplement:
+
+ my $object = Qt::<classname>(arg_1, ..., arg_n);
+
+Un constructeur sans argument s'énonce encore plus brièvement :
+
+ my $object = Qt::<classname>;
+
+
+=item 3
+
+Comme il a déjà été dit, l'équivalent Perl d'un pointeur C++ est le mot-clé
+Perl B<undef>.
+
+Les pointeurs sont les arguments précédés par le caractère B<*> dans la
+documentation Qt (Par exemple: "C<QWidget* widget>").
+
+=back
+
+=head2 L'héritage et les objets
+
+Avant d'expliquer comment les routines Perl peuvent être appelées de Qt,
+parlons du mécanisme d'héritage vu de PerlQt.
+
+PerlQt est conçu pour allier la simplicité de Qt à la puissance et à la
+flexibilité de Perl. Pour ce faire, PerlQt étend le paradigme objet de
+Perl pour mimer Qt et son mécanisme de B<métaobjets>.
+
+=head3 Un Widget personnalisé
+
+Réécrivons le programme "Hello World!" avec une version personnalisée
+de PushButton:
+
+ 1: use strict;
+ 2:
+ 3: package Button;
+ 4: use Qt;
+ 5: use Qt::isa qw(Qt::PushButton);
+ 6:
+ 7: sub NEW
+ 8: {
+ 9: shift->SUPER::NEW(@_[0..2]);
+ 10: resize(130, 40);
+ 11: }
+ 12:
+ 13: 1;
+ 14:
+ 15: package main;
+ 16:
+ 17: use Qt;
+ 18: use Button;
+ 19:
+ 20: my $a = Qt::Application(\@ARGV);
+ 21: my $w = Button("Hello World!", undef);
+ 22: $a->setMainWidget($w);
+ 23: $w->show;
+ 24: exit $a->exec;
+
+Pour implanter notre propre version de PushButton, nous créons un nouveau
+package [l.3] et importons Qt [l.4].
+
+Nous utilisons le pragma C<Qt::isa> [l.5] pour déclarer notre widget
+comme sous-classe de PushButton. Ce pragma accepte une liste de une ou
+plusieurs classes dont dérive la classe à définir.
+
+Créons maintenant un constructeur pour notre nouveau widget
+en écrivant une routine appelée B<NEW> I<(notez les majuscules qui
+marquent une méthode différente du constructeur "new" usuel)>.
+Le constructeur PerlQt est appelé B<implicitement> I<comme ligne 21>.
+
+Note widget doit d'abord appeler le constructeur de sa classe de base
+(ici: Qt::PushButton) à la ligne 9, avec tous les arguments que nous
+avons reçus.
+
+Nous créons ainsi un objet instance de notre classe. Cette objet est
+accessible par la fonction B<this> (Attention: ce n'est pas la
+variable C<$this> mais simplement C<this>).
+
+Chaque fois que nous invoquons une méthode à partir de notre package
+nous pouvons écrire indifféremment C<method()> ou
+C<this-E<gt>method()>;
+
+=head3 L'utilisation d'attributs
+
+Lors de la construction d'un objet composite, vous pouvez simplement créer
+ses différents composants à l'intérieur de variables de scope lexical
+(c.à.d déclarées par B<my>) puisque les widgets sont seulement détruits
+par leur parent et non nécessairement quand leur conteneur disparaît
+du scope.
+
+En d'autres termes, PerlQt utilise un système de comptage de
+références pour gérer la destruction des objets.
+
+Souvent cependant, vous souhaiterez accéder aux composants de votre objet depuis
+un tout autre endroit que celui où vous l'avez créé (par exemple pour modifier une
+légende de bouton dynamiquement). Dans ce cas, la syntaxe traditionnelle de perl
+propose de stocker une référence à ces composants dans la table associative (hash) de
+l'objet lui-même. Mais cette syntaxe s'avère peu pratique à l'usage et beaucoup
+trop libre - il n'y a pas de vérification à la compilation de sorte que vous pouvez
+accéder à des clefs non existantes sans déclencher d'erreur.
+
+En lieu et place de cette syntaxe, PerlQt introduit le concept d'B<attributs>.
+
+Les attributs sont de simples variables perl, écrites sans le signe dollar initial, et
+pouvant contenir toute donnée qui est une propriété de votre objet.
+Leur principal avantage est de fournir une syntaxe très rapide et vérifiable à la compilation.
+
+Pour définir et pouvoir utiliser de nouveaux attributs, il suffit d'utiliser
+le pragma C<use Qt::attributes>, suivi d'une liste des noms d'attributs souhaités.
+Ainsi:
+
+
+ 1: use strict;
+ 2:
+ 3: package Button;
+ 4: use Qt;
+ 5: use Qt::isa qw(Qt::PushButton);
+ 6: use Qt::attributes qw(
+ 7: itsTime
+ 8: pData
+ 9: );
+ 10:
+ 11: sub NEW
+ 12: {
+ 13: shift->SUPER::NEW(@_[0..2]);
+ 14: itsTime = Qt::Time;
+ 15: itsTime->start;
+ 16: pData->{'key'} = " Foo ";
+ 17: }
+ 18:
+ 19: sub resizeEvent
+ 20: {
+ 21: setText( "w: ". width() ." h: ". height() .
+ 22: "\nt: ". itsTime->elapsed . pData->{'key'} );
+ 23: }
+ 24:
+ 25: 1;
+
+=for html
+<br/>
+<div class='image'><img src="../images/ex2.png"/></div>
+
+
+L'attribut itsTime est déclaré à la ligne 7 et initialisé par un objet C<Qt::Time>
+à la ligne 14.
+
+Puisque nous réimplémentons la fonction virtuelle "resizeEvent"
+[l.19], chaque fois que le widget principal est redimensionné, cette
+fonction "resizeEvent" sera déclenchée et le texte de notre Button mis
+à jour avec les valeurs venant de l'objet [1.21] et les attributs que
+nous avons définis [1.22].
+
+B<Récapitulation>
+
+=over 4
+
+=item *
+
+Pour hériter d'une classe Qt, un package doit contenir un
+pragma C<use Qt::isa>.
+
+Ainsi:
+
+ use Qt::isa "Qt::widget";
+
+=item *
+
+Le constructeur d'objet est nommé B<NEW> et est appelé implicitement.
+Vous ne devez donc pas dire:
+
+ my $o = MyButton->NEW("Hello");
+
+Mais bien :
+
+ my $o = MyButton("Hello");
+
+=item *
+
+A l'intérieur d'un package, on accéde l'instance courante par la
+fonction B<this>.
+
+Quand une fonction membre est appelée, les arguments sont accessibles
+par le tableau B<@_>, mais le premier élément de B<@_> n'est pas une
+référence à l'objet contrairement à l'usage commun en Perl.
+
+Vous ne pouvez donc pas dire :
+
+ sub myMember
+ {
+ my $moi = shift;
+ my $arg = shift;
+ $arg->doThat($moi);
+ $moi->doIt;
+ }
+
+Écrivez plutôt :
+
+ sub myMember
+ {
+ my $arg = shift;
+ $arg->doThat(this);
+ doIt();
+ }
+
+De plus, si vous voulez appeler une méthode dans une classe de base à
+partir d'une classe dérivée, utilisez l'attribut spécial SUPER :
+
+ sub exemple
+ {
+ print "Appel de la méthode 'exemple' dans la classe de base";
+ SUPER->exemple(@_)
+ }
+
+Notez aussi que la construction :
+
+ this->SUPER::Exemple(@_);
+
+est possible, mais qu'elle passe l'objet comme premier argument.
+
+=item *
+
+Lorsque vous devez stocker dans votre package un objet contenu, vous
+devez le définir comme B<attribut> :
+
+ use Qt::attributes qw(
+ firstAttribute
+ ...
+ lastAttribute);
+
+Il sera alors disponible comme accesseur :
+
+ firstAttribute = myContainedWidget( this );
+ firstAttribute->resize( 100, 100 );
+
+B<NB:> Pour ceux qui souhaitent en savoir plus, les attributs sont implémentés
+à l'aide de sub lvalue, c'est à dire de fonctions assignables.
+En interne, elles ne font que pointer sur la clef de hachage correspondante dans
+l'objet B<this>, ce qui rend les tournures "unAttribut->fonction()" et
+"this->{'unAttribut'}->fonction()" strictement équivalentes
+(si ce n'est que la première est vérifiée au moment de la compilation).
+
+=item *
+
+Pour réimplémenter une B<fonction virtuelle>, créez simplement une
+B<sub> de même nom que cette fonction.
+
+Les fonctions virtuelles existantes sont marquées comme telles dans
+la documentation de Qt (ce sont les méthodes précédées du mot clef "virtual").
+
+Vous pouvez visualiser les noms de méthodes virtuelles que Qt tentera d'appeler
+dans votre classe en plaçant C<use Qt::debug qw|virtual|> en tête de
+votre programme.
+
+=back
+
+=head2 Signaux et Slots
+
+Voyons maintenant comment les objets Qt peuvent communiquer entre eux
+de manière à ce qu'un événement concernant un objet puisse déclencher
+l'exécution d'une routine en un quelconque endroit de votre programme.
+
+Dans d'autres toolkits, les callbacks (appels en retour) sont généralement
+utilisés à cet effet. Mais Qt dispose d'un mécanisme beaucoup plus puissant
+et plus flexible : les B<Signaux et Slots>.
+
+On peut se le représenter comme le cablage entre les composants d'une
+chaîne Hi-Fi. Un amplificateur, par exemple, émet des signaux de sortie
+sans chercher à savoir si des enceintes lui sont connectées ou non.
+Un magnétophone peut attendre un signal sur sa prise d'entrée
+pour commencer à enregistrer, et il ne cherchera pas à savoir s'il est
+l'unique destinataire de ce signal ou si ce dernier est aussi reçu par un graveur de CD
+ou écouté au casque.
+
+Un composant Qt se comporte comme notre amplificateur ou notre
+magnétophone. Il a des sorties ou B<Signaux> et des entrées ou
+B<Slots>. Chaque sortie (signal) est connectable à un nombre illimité
+d'entrées (slots). La sortie d'un composant peut être potentiellement
+branchée à toute entrée d'un composant (y compris lui-même),
+
+
+La syntaxe de ce système de connexion est soit:
+
+Qt::Object::connect( envoyeur, SIGNAL 'mon_signal(types_d_arguments)',
+recepteur, SLOT 'monslot(types_d_arguments)');
+
+soit:
+
+unObjet->connect( envoyeur, SIGNAL 'mon_signal(types_d_arguments)',
+SLOT 'monslot(types_d_arguments)');
+
+Dans le second cas, le récepteur est omis car c'est l'objet lui-même,
+
+Ce mécanisme est extensible à volonté par la déclaration de nouveaux Signaux et
+Slots par l'usage des pragma C<use Qt::signals> et C<use Qt::slots>
+(voir aussi la deuxième syntaxe décrite plus bas).
+
+Chaque slot déclaré appellera la routine correspondante de votre
+objet. Chaque signal déclaré peut être déclenché via le mot-clé B<emit>.
+
+B<Réécrivons encore notre exemple pour illustrer nos propos :>
+
+ 1: use strict;
+ 2:
+ 3: package Button;
+ 4: use Qt;
+ 5: use Qt::isa qw(Qt::PushButton);
+ 6: use Qt::attributes qw(itsTime);
+ 7: use Qt::slots
+ 8: aEteClicke => [],
+ 9: changement => ['int', 'int'];
+ 10: use Qt::signals
+ 11: changeLe => ['int', 'int'];
+ 12:
+ 13: sub NEW
+ 14: {
+ 15: shift->SUPER::NEW(@_[0..2]);
+ 16: itsTime = Qt::Time;
+ 17: itsTime->start;
+ 18: this->connect(this, SIGNAL 'clicked()', SLOT 'aEteClicke()');
+ 19: this->connect(this, SIGNAL 'changeLe(int,int)', SLOT 'changement(int,int)');
+ 20: }
+ 21:
+ 22: sub aEteClicke
+ 23: {
+ 24: my $w = width();
+ 25: my $h = height();
+ 26: setText( "w: $w h: $h\nt: ". itsTime->elapsed );
+ 27: emit changeLe($w, $h);
+ 28: }
+ 29:
+ 30: sub changement
+ 31: {
+ 32: my ($w, $h) = @_;
+ 33: print STDERR "w: $w h: $h \n";
+ 34: }
+ 35:
+ 36: 1;
+
+Nous définissons dans ce package deux nouveaux slots et un nouveau signal.
+
+
+La documentation Qt nous dit que tout PushButton clické émet un signal
+C<clicked()> ; nous le connectons donc à notre nouveau slot [ligne 18].
+
+Nous connectons aussi notre signal C<ChangeLe> à notre slot
+C<changement>.
+
+Ainsi, quand on appuie (clique) sur notre Button , le signal
+C<clicked()> est émit et déclenche le slot C<aEteClicke()>.
+C<aEteClicke()> émet à son tour le signal C<changeLe(int,int)>[l.27],
+appelant de ce fait le slot C<changement(int,int)>, avec deux arguments.
+
+Enfin, il existe une syntaxe alternative introduite dans PerlQt-3.008 :
+
+ sub un_slot : SLOT(int, QString)
+ {
+ $int = shift;
+ $string = shift;
+ # faire quelque chose
+ }
+
+et
+
+ sub un_signal : SIGNAL(QString);
+
+Cette syntaxe est parfaitement compatible avec la déclaration par le biais de
+C<use Qt::signals> et C<use Qt::slots>.
+Il peut d'ailleurs d'avérer très profitable pour la clarté du programme de déclarer tout d'abord
+les signaux/slots au moyen de C<use Qt::slots/signals>, puis de rappeler cette déclaration au niveau de
+l'implémentation à l'aide de la seconde syntaxe.
+Les déclarations seront alors vérifiées à la compilation, et le moindre conflit
+générera un avertissement.
+
+=head1 Développement rapide (RAD) avec Qt Designer et Puic
+
+
+=head2 Introduction
+
+=over 4
+
+=item * N.B:
+
+Depuis la version 3.008, il existe un plugin spécifique à PerlQt pour Qt Designer.
+Ce plugin (disponible sur les pages internet du projet) apporte le confort d'une intégration poussée,
+la coloration syntaxique Perl, la complétion automatique, et permet de lancer et déboguer un projet
+sans quitter l'interface du Designer.
+Ce qui suit reste néanmoins parfaitement valable pour ce qui est de l'utilisation de puic en ligne de commande,
+et pour l'utilisation de Qt Designer I<sans> le plugin spécifique.
+
+=back
+
+Aussi puissant et intuitif que soit Qt, écrire une GUI complète reste un exercice
+fastidieux.
+
+Heureusement, Qt est fourni avec un constructeur de GUI sophistiqué
+appelé Qt Designer qui est quasiment un environnement de développement
+intégré. Il comporte la gestion de Projets, la création d'un GUI par
+des actions de "drag and drop", un butineur d'objet complet,
+l'interconnexion graphique de signaux et de slots, et plus encore.
+
+L'information générée par Qt Designer's est en format XML et peut donc
+être parsée par différentes commandes comme dont B<puic> (le
+compilateur d'interface utilisateur PerlQt).
+
+Supposons que vous avez déja construit un fichier d'interface avec
+Qt Designer, la transcription en un programme PerlQt se fait par
+la simple exécution de la commande :
+
+ puic -x -o program.pl program.ui
+
+Cela génèrera le package défini dans votre fichier ui et un package
+principal à fins de test,
+
+Vous pouvez préférer :
+
+ puic -o package.pm program.ui
+
+Cela ne générera que le package qui pourra être utilisé par un programme séparé.
+
+=head2 Inclure des Images
+
+
+Il y a deux manières d'inclure des B<images ou icônes>:
+
+=over 4
+
+=item * Inclusion Inline
+
+A cette fin, nous devons sélectionner "Edit->Form
+Settings->Pixmaps->Save inline" dans Qt Designer et executer ensuite:
+
+ puic -x -o F<program.pl> F<program.ui>
+
+
+=item * Image Collection
+
+Cette stratégie est plus complexe, mais plus propre et plus puissante.
+
+ puic -o F<Collection.pm> -embed F<unique_identifier> F<image-1> ... F<image-n>
+
+Ajoutez l'instruction C<use Collection.pm> dans le package principal
+de votre programme.
+
+Si vous avez créé un fichier projet dans Qt Designer et ajouté toutes
+les images dans un groupe (par "Project->Image Collection"), vous
+disposez ensuite de ces images dans le répertoire où votre fichier
+projet (*.pro) est stocké, dans le sous-répertoire B<image>. Vous pouvez
+alors générer la collection d'images par:
+
+ puic -o F<Collection.pm> -embed F<identifier> images/*
+
+Vous pouvez utiliser autant de collections d'images que vous voulez
+dans un programme en ajoutant simplement une instruction B<use>
+pour chaque collection.
+
+=back
+
+=head2 Travailler avec des fichiers B<.ui>
+
+Souvent, vous voudrez regénérez votre interface utilisateur à
+à cause d'une modification ou extension de votre design initial.
+C'est donc une mauvais idée d'écrire votre code dans le fichier Perl
+autogénéré car vous risquerez d'écraser le code que vous avez écrit
+manuellement ou vous devrez faire des copier-coller intensifs.
+
+Voici une meilleure méthode :
+
+=over 4
+
+=item * Écrire l'implémentation de slots dans le Designer
+
+Dans Qt Designer, selectionnez l'onglet I<Source> dans l'explorateur
+d'objets (B<Object Explorer>). Vous pouvez ainsi voir représentées
+sous forme d'arbre les classes que vous avez générées. Maintenant, si
+vous cliquez deux fois sur l'entrée I<Slots/public>,
+un dialogue vous demande si vous voulez créer un nouveau slot pour
+votre module. Une fois cela fait, le nouveau slot apparait à
+l'intérieur de l'arbre l'explorateur d'objet; cliquer dessus vous
+amènera à votre fichier B<E<lt>Votre ClasseE<gt>.ui.h> où vous pouvez
+écrire l'implémentation de votre slot.
+
+Par défaut, il devrait ressembler à ceci :
+
+ void Form1::newSlot()
+ {
+
+ }
+
+
+La déclaration du slot est réellement du code C++, mais ignorons cela
+et écrivons du code Perl entre les deux accolades en faisant bien
+attention d'indenter notre code avec au moins un espace.
+
+ void Form1::newSlot()
+ {
+ print STDERR "Hello world from Form1::newSlot();
+ if(this->foo())
+ {
+ # faire quelque chose
+ }
+ }
+
+Notre code Perl ainsi écrit sera sauvé dans le fichier ui.h et
+B<puic> prendra soin de le placer dans notre programme final.
+
+Ici, après l'exécution de B<puic> sur le ficier Form1.ui, vous
+devriez avoir:
+
+ sub newSlot
+ {
+ print STDERR "Hello world from Form1::newSlot();
+ if(this->foo())
+ {
+ # faire quelque chose
+ }
+ }
+
+=item * Sous-classez votre GUI
+
+En utilisant l'option I<-subimpl> de B<puic>, vous pouvez générer un
+module dérivé qui hérite l'interface utilisateur originelle.
+
+Typiquement, vous générez le module dérivé une fois, et écrivez votre
+code dans ce module dérivé. Ainsi, quand vous devez modifier votre
+module GUI, regénérez le module dont il dérive et il héritera les
+changements.
+
+Pour générer le module de base :
+
+ puic -o Form1.pm form1.ui
+
+(faîtes cela aussi souvent que nécessaire: n'éditez jamais
+manuellement form1.ui puisqu'il serait écrasé)
+
+
+Pour générer le GUI dérivé :
+
+ puic -o Form2.pm -subimpl Form2 form1.ui
+
+ou
+
+ puic -o program.pl -x -subimpl Form2 form1.ui
+
+(faites cela une fois et travaillez avec le fichier résultant)
+
+=back
+
+=head1 Autres outils de développement
+
+PerlQt comprend également deux programmes pouvant vous aider à maîtriser l'API de Qt :
+
+=head2 pqtapi
+
+pqtapi est un outil d'introspection en ligne de commande.
+
+ utilisation: pqtapi [-r <re>] [<class>]
+
+ options:
+ -r <re> : chercher les méthodes correspondant à l'expression régulière <re>
+ -i : avec -r, effectue une recherche insensible à la casse
+ -v : afficher les versions de PerlQt et de Qt
+ -h : afficher ce message d'aide
+
+ex:
+
+ $>pqtapi -ir 'setpoint.* int'
+ void QCanvasLine::setPoints(int, int, int, int)
+ void QPointArray::setPoint(uint, int, int)
+
+=head2 pqtsh
+
+B<pqtsh> est un shell graphique permettant de tester l'API de manière interactive.
+Un exemple dynamique est accessible dans l'entrée de menu C<Help-E<gt>Example>.
+
+=for html
+<br/>
+<div class='image'><img src="../images/pqtsh.png"/></div>
+
+=head1 Limitations
+
+Les classes à modèle (templates) ne sont pas encore accessibles par PerlQt.
+En revanche, les classes dérivées de classes à modèle sont disponibles.
+
+Vous pouvez reconnaître ce type de classe en ce que leurs arguments comprennent un type générique placé entre
+les signes "<" et ">".
+
+ex:
+ QDictIterator ( const QDict<type> & dict )
+
+
+=head1 Crédits
+
+PerlQt-3 est (c) 2002 Ashley Winters (et (c) 2003 Germain Garand)
+
+Kalyptus et l'engin de génération Smoke sont (c) David Faure and Richard Dale
+
+Puic is (c) TrollTech AS., Phil Thompson et Germain Garand,
+
+Ledit logiciel est délivré sous la GNU Public Licence v.2 or later.
+
+
+=head1 Appendice: Les conventions de C++ et leur traduction en Perl
+
+Lorsque vous voulez utiliser depuis PerlQt une classe ou méthode décrite
+dans la L<documentation|"http://doc.trolltech.com"> Qt (voyez aussi le programme
+$QTDIR/bin/assistant livré avec Qt), vous devez suivre des règles de translation simples.
+
+=over 4
+
+=item Noms de classe
+
+=over 4
+
+=item *
+
+Les noms de classes utilisent le préfixe B<Qt::> au lieu de B<Q> pour
+être conforme à l'usage Perl. Ainsi: QComboBox est nommé Qt::ComboBox
+dans PerlQt.
+
+=back
+
+=item Fonctions
+
+=over 4
+
+=item *
+
+Les fonctions décrites comme B<static> sont accédées directement et non
+à travers un objet. Ainsi la fonction statique Foo de la classe B<QBar>
+peut être accédée de PerlQt par
+
+ Qt::Bar::Foo( arg-1,...,arg-n);
+
+=item *
+
+Les fonctions décrites comme B<members> ou B<Signals> sont
+accessibles à travers l'objet par l'opérateur
+ B<-E<gt>> .
+Par exemple:
+
+ $widget->show;
+
+Il n'y a pas de différence fondamentale entre les méthodes et les
+signaux, néanmoins PerlQt fournit le mot-clé B<emit> comme une
+mnémonique pratique pour rendre clair que vous émettez un signal :
+
+ emit $button->clicked;
+
+=back
+
+=item Arguments
+
+=over 4
+
+=item * Par valeur
+
+Lorsqu'un argument n'est pas précédé par un des caractères B<&> or
+B<*>, il est passé par valeur. Pour tous les types basiques tels que
+int, char, float and double, PerlQt convertira automatiquement les
+valeurs litérales et scalaires dans le type correspondants C++.
+
+Ainsi pour le prototype d'un constructeur écrit dans la documentation
+comme ceci:
+ QSize ( int w, int h )
+
+
+Vous écrirez :
+
+ Qt::Size(8, 12);
+
+=item * Par référence
+
+Lorsqu'un argument est précédé par le caractère B<&>, Il est une
+référence à un objet ou à un type. Vous pouvez alors fournir un nom de
+variable ou un objet temporaire :
+
+ $keyseq = Qt::keySequence( &Qt::CTRL + &Qt::F3 );
+ $widget->setAccel( $keyseq );
+
+ou
+
+ $widget->setAccel(Qt::keySequence( &Qt::CTRL + &Qt::F3 );
+
+Si l'argument n'est I<pas> qualifié par B<const> (constante), l'argument
+est un objet qui peut être altéré par la méthode, vous devez
+donc passer une variable.
+
+=item * Par pointeur
+
+Lorsqu'un argument est précédé par le caractère B<*>,
+un pointeur vers un objet ou un type est attendu. En PerlQt, vous
+pouvez fournir un nom de variable ou le mot clé B<undef> à la place
+du pointer Null.
+
+De plus, si l'argument est const, l'objet passé en argument est en
+lecture seule: il ne peut pas être modifié.
+
+=back
+
+=item Énumérations
+
+Les Énumerations sont une forme d'alias pour des valeurs numériques
+dont il serait autrement difficile de se souvenir:
+
+Exemple C++:
+
+ enum Strange { Apple, Orange, Lemon }
+
+Ici, C<Strange> est le type (au sens de C++) de l'énumération, et
+C<Apple>, C<Orange> et
+C<Lemon> ses valeurs possible , qui sont des aliases pour des
+nombres (ici 0, 1 et 2)
+
+L'accès aux valeurs d'énumération en Perl Qt est un appel
+de fonction statique.
+
+Donc, si vous voulez éviter des prblèmes de lisibilité, nous vous
+recommandons l'usage d'une syntaxe alternative d'appel de fonction
+pour marquer l'utilisation d'un alias d'énumération: C<&fonction>.
+
+
+Revenons à notre exemple C<Strange>.
+
+Si nous rencontrons sa définition dans la classe C<QFruits>, vous
+écrirez en PerlQt :
+
+ $pomme_plus_orange = &Qt::Fruit::Pomme + &Qt::Fruit::Orange;
+
+=item Opérateurs
+
+Dans PerlQt, la B<surcharge d'opérateurs> fonctionne de manière transparente.
+Si un opérateur est surchargé dans une classe Qt (ce qui signifie que son utilisation
+déclenchera un appel de méthode, au lieu d'utiliser l'opérateur générique)
+il sera également surchargé dans PerlQt.
+
+ex-1: surcharge de '+='
+
+ $p1 = Qt::Point(10, 10)
+ $p2 = Qt::Point(30,40)
+ $p2 += $p1; # $p2 devient (40,50)
+
+ex-2: surcharge de '<<'
+
+ $f = Qt::File("example");
+ $f->open( IO_WriteOnly ); # voir l'entrée 'Constantes' plus bas
+ $s = Qt::TextStream( $f );
+ $s << "Que faire avec " << 12 << " pommes ?";
+
+
+B<Exception notable> : le constructeur de copie (signe égal, '=') n'est jamais surchargé,
+attendu qu'il ne pourrait fonctionner que partiellement et que le paradigme de
+Perl est très différent de C++ en matière de copie d'objets.
+
+=item Constantes
+
+Qt n'utilise pas beaucoup de constantes, mais on en trouve cependant dans le module d'Entrées/Sorties,
+où elles font office de drapeaux pour les modes d'ouverture de fichiers.
+
+Pour éviter de polluer inutilement l'espace de nom, nous avons regroupé les constantes dans le module
+B<Qt::constants>, d'où elles seront chargées à la demande.
+
+Ainsi, pour importer l'ensemble des constantes d'E/S, on écrira :
+
+ use Qt::constants;
+
+Et pour importer quelques symboles seulement :
+
+ use Qt::constants qw( IO_ReadOnly IO_WriteOnly );
+
+=item Fonctions globales
+
+Qt dispose de fonctions utilitaires, telles bitBlt, qCompress, etc.
+
+Ces fonctions ont été rassemblées dans un espace de nom commun:
+C<Qt::GlobalSpace>.
+
+Vous pourrez donc y accéder soit par un appel pleinement qualifié :
+
+ Qt::GlobalSpace::qUncompress( $buffer )
+
+Soit en important préalablement ces fonctions dans l'espace de nom courant :
+
+ use Qt::GlobalSpace;
+ qUncompress( $buffer )
+
+Bien entendu, vous pouvez aussi n'importer que les fonctions souhaitées :
+
+ use Qt::GlobalSpace qw( qUncompress bitBlt )
+
+B<N.B:> GlobalSpace renferme également des opérateurs de portée globale, tels
+celui permettant d'aditionner deux Qt::Point(). Ces opérateurs seront appelés
+automatiquement.
+
+ex:
+
+ $p1 = Qt::Point(10, 10) + Qt::Point(20, 20)
+
+=back
+
+=head1 Annexe 2 : Internationalisation
+
+PerlQt résout les problèmes d'internationalisation en convertissant systématiquement les B<QString>
+de Qt en B<utf8> côté Perl.
+
+Les conversions en sens inverse, depuis Perl vers Qt sont traitées différemment suivant le contexte :
+
+=over 4
+
+=item * Si la chaîne de caractère est déjà marquée comme étant utf8
+
+alors elle sera convertie en QString directement.
+
+C'est la manière privilégiée d'opérer, et la plus simple :
+Il vous suffit d'insérer un pragma B<use utf8> en tête de vos programmes, puis d'utiliser un éditeur de
+texte supportant l'utf8 (quasiment tous de nos jours) pour élaborer votre code source.
+Les chaînes seront marquées par Perl automatiquement.
+
+=item * Si la chaîne n'est pas marquée comme utf8, et le pragma 'use locale' n'est pas actif
+
+alors la conversion en QString se fera depuis l'B<ISO-Latin-1>.
+
+=item * Si la chaîne n'est pas marquée comme utf8, et le pragma 'use locale' est actif
+
+alors la conversion en QString se fera depuis votre B<locale>.
+
+=back
+
+Lorsque des chaînes contiennent de l'utf8, Perl adapte automatiquement ses opérateurs pour que
+leur gestion soit entièrement transparente (comprendre opaque, comme toujours...).
+Cependant, vous pourrez avoir besoin à l'occasion de les transcrire en d'autres jeux d'encodage.
+Ceci peut se faire soit avec Qt :
+
+ $tr1=Qt::TextCodec::codecForLocale(); # ceci utilisera la locale en vigueur
+ $tr2=Qt::TextCodec::codecForName("KOI8-R"); # ceci force l'emploi d'une locale spécifique (Russe)
+
+ print $tr1->fromUnicode(Qt::DateTime::currentDateTime()->toString)."\n\n";
+ print $tr2->fromUnicode($une_chaine_utf8);
+
+Soit avec les outils de Perl (pour perl >= 5.8.0).
+Se reporter à ce sujet à la documentation du module B<Encode> (C<perldoc Encode>).
+
+=head3 désactiver l'encodage utf8
+
+Les programmeurs souhaitant désactiver temporairement l'encodage utf8
+(pour la gestion de programmes externes ou de modules anciens ne supportant pas cet encodage)
+pourront utiliser le pragma B<use bytes> (et sa réciproque : B<no bytes>).
+
+Dans la portée de ce pragma, les conversions depuis QString vers les chaînes Perl se feront en ISO-Latin1
+(par défaut) ou suivant la locale en vigueur (si B<use locale> est actif).
+
+Notez bien qu'il est préférable de I<ne pas utiliser ce pragma à la légère>, en ce qu'il ruine totalement les
+efforts de standardisations autour d'utf8 entrepris depuis plusieurs années déjà.
+Il est très préférable de corriger les programmes fautifs.
+
+=head1 Annexe 3 : Canaux de déboguage
+
+Le module B<Qt::debug> offre divers canaux de déboguage permettant de filtrer
+le flux conséquent d'informations disponibles pour l'adapter à vos besoins.
+
+ use Qt::debug;
+
+ use Qt::debug qw|calls autoload verbose|;
+
+Avec le pragma C<use Qt::debug>, seuls les canaux B<verbose> et B<ambiguous> sont activés.
+Si vous le faites suivre d'une liste précise de canaux, seuls ceux-ci seront affichés.
+
+B<Liste et descriptif des canaux :>
+
+=over 4
+
+=item * ambiguous
+
+Vérifier si les appels de méthodes sont ambigus, et dire quelle méthode, parmi le jeux
+d'alternatives, à finalement été choisie.
+
+=item * verbose
+
+Donner davantage d'informations.
+
+Utilisé avec B<ambiguous>, vous donnera les correspondances les plus proches lorsqu'un appel de méthode échoue.
+
+ex:
+
+ use Qt;
+ use Qt::debug;
+ $a= Qt::Application(\@ARGV);
+ $a->libraryPath("chose");
+
+ --- No method to call for :
+ QApplication::libraryPath('chose')
+ Closer candidates are :
+ static void QApplication::addLibraryPath(const QString&)
+ static QStringList QApplication::libraryPaths()
+ static void QApplication::removeLibraryPath(const QString&)
+ static void QApplication::setLibraryPaths(const QStringList&)
+
+=item * calls
+
+Pour chaque appel de méthode, vous dira quelle méthode Qt est finalement appelée,
+en précisant les arguments si B<verbose> est actif.
+
+=item * autoload
+
+Détaille le passage dans le code intermédiaire faisant la jonction entre Perl et Qt.
+
+=item * gc
+
+Donne des informations sur la collection des déchets, c'est à dire sur la destruction des objets,
+qu'ils soient détruits depuis Perl ou Qt.
+
+=item * virtual
+
+Vous averti chaque fois qu'une fonction virtuelle tente d'accéder à sa réimplémentation en Perl
+(que cette réimplémentation existe ou non).
+
+=item * all
+
+Activer tous les canaux.
+
+=back
+
+=head1 Annexe 4 : Marshalleurs
+
+Un marshalleur est un convertisseur permettant de transcrire un type de données en un autre.
+
+Dans PerlQt, la plupart des objets Qt gardent leurs propriétés d'objet, ce qui permet d'invoquer leurs méthodes
+et de changer leurs propriétés comme il se doit.
+Cependant, il arrive que l'objet d'origine corresponde à ce point à un type natif de Perl qu'il serait malséant
+d'utiliser l'interface C++ et beaucoup plus naturel de lui substituer son équivalent.
+
+Ici interviennent les marshalleurs.
+Plutôt que de retourner un objet Qt::StringList, qui serait délicat à manipuler,
+PerlQt le transformera en référence de liste Perl.
+Dès lors, tous les opérateurs de manipulation de liste pourront lui être appliqué :
+on gagne en densité, en cohérence et en simplicité.
+
+Cette transformation s'appliquera aussi en sens inverse, et n'importe quelle liste de chaînes Perl
+pourra être donnée en argument à une méthode attendant une Qt::StringList.
+
+ Liste des marshalleurs (PerlQt-3.008)
+ -----------------------------------------------------------------
+ float, double <=> réel Perl (NV)
+ char, uchar, int, uint, enum
+ long, ulong, short, ushort <=> entier Perl (IV)
+ QString, -&, -* => chaîne Perl (utf8)
+ QString, -&, -* <= chaîne Perl (utf8 ou iso-latin1 ou locale)
+ QCString, -&, -* <=> chaîne Perl (utf8 ou octets, suivant contenu ou pragma "bytes")
+ QStringList, -&, -* => référence à une liste de chaînes Perl (utf8)
+ QByteArray, -&, -* <=> chaîne Perl (octets)
+ int&, -* <=> entier Perl (IV)
+ bool&, -* <=> booléen Perl
+ char* <=> chaîne Perl (octets)
+ char** <= référence à une liste de chaînes Perl (octets)
+ uchar* <= chaîne Perl(octets)
+ QRgb* <= référence à une liste d'entiers Perl (IV)
+ QCOORD* <= référence à une liste d'entiers Perl (IV)
+ void* <=> référence à un entier Perl (IV)
+ QValueList<int>, - *, - & <=> référence à une liste d'entiers Perl (IV)
+ QCanvasItemList, - *, - & => réference à une liste de Qt::CanvasItem
+ QWidgetList, - *, - & <=> réference à une liste de Qt::Widget
+ QObjectList, - *, - & <=> réference à une liste de Qt::Object
+ QFileInfoList, - *, - & <=> réference à une liste de Qt::FileInfo
+ QPtrList<QTab>, - *, - & <=> réference à une liste de Qt::Tab
+ QPtrList<QToolBar>, - *, - & <=> réference à une liste de Qt::ToolBar
+ QPtrList<QNetworkOperation>, - *, - & <=> réference à une liste de Qt::NetworkOperation
+ QPtrList<QDockWindow>, - *, - & <=> réference à une liste de Qt::DockWindow
+ (QUObject*)
+