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