diff options
author | Timothy Pearson <[email protected]> | 2011-12-18 03:08:08 -0600 |
---|---|---|
committer | Timothy Pearson <[email protected]> | 2011-12-18 03:08:08 -0600 |
commit | bcc95cd92ca12c1783464b8ada6816d430dc0e98 (patch) | |
tree | 4701c447365db5392df0174b4bb00b5b5c369da4 /doc | |
download | libtqt-perl-bcc95cd92ca12c1783464b8ada6816d430dc0e98.tar.gz libtqt-perl-bcc95cd92ca12c1783464b8ada6816d430dc0e98.zip |
Initial import of libqt-perl (not yet TQt compatible)
Diffstat (limited to 'doc')
-rw-r--r-- | doc/css/pod.css | 132 | ||||
-rw-r--r-- | doc/en/Makefile | 7 | ||||
-rw-r--r-- | doc/en/PerlQt.pod | 1147 | ||||
-rw-r--r-- | doc/en/index.html | 1081 | ||||
-rw-r--r-- | doc/fr/Makefile | 7 | ||||
-rw-r--r-- | doc/fr/PerlQt.pod | 1189 | ||||
-rw-r--r-- | doc/fr/index.html | 1120 | ||||
-rw-r--r-- | doc/images/ex1.png | bin | 0 -> 2569 bytes | |||
-rw-r--r-- | doc/images/ex2.png | bin | 0 -> 3578 bytes | |||
-rw-r--r-- | doc/images/pqtsh.png | bin | 0 -> 55385 bytes |
10 files changed, 4683 insertions, 0 deletions
diff --git a/doc/css/pod.css b/doc/css/pod.css new file mode 100644 index 0000000..6f7bd52 --- /dev/null +++ b/doc/css/pod.css @@ -0,0 +1,132 @@ +/* standard elements */ +body + { + background: #FFFFFF; + font-family: Verdana, Arial, Helvetica, sans-serif; + font-weight: normal; + } +p + { + color: #000000; + font-family: Verdana, Arial, Helvetica, sans-serif; + font-weight: normal; + } +blockquote + { + color: #000000; + font-family: Verdana, Arial, Helvetica, sans-serif; + font-weight: normal; + } +ul + { + color: #000000; + font-family: Verdana, Arial, Helvetica, sans-serif; + font-weight: normal; + list-style-type: disc; + } +ol + { + color: #000000; + font-family: Verdana, Arial, Helvetica, sans-serif; + font-weight: normal; + } +h1 + { + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 18px; + font-weight: bold; + color: #2660C9; + } +h2 + { + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 13px; + font-weight: bold; + color: #2660C9; + background-color: #EAE2BB; + } +h3 + { + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 12px; + font-weight: bold; + color: #000000; + } +h4 + { + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 11px; + font-weight: bold; + color: #2660C9; + } + +pre + { + font-size: 120%; + padding-bottom: 5px; + } +tt + { + font-size: 120%; + } +code + { + font-size: 120%; + } +kbd + { + font-size: 120%; + } + +/* documentation link formatting */ +a:link + { + color: #2660C9; + text-decoration: underline; + } +a:visited + { + color: #2660C9; + text-decoration: underline; + } +a:hover + { + color: #000000; + text-decoration: underline; + } +a:active + { + color: #2660C9; + text-decoration: underline; + } +.docsubheading + { + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 13px; + font-weight: bold; + color: #B82619; + background-color: #EAE2BB; + } +.docsubheadinggrey + { + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 13px; + font-weight: bold; + color: #B82619; + background-color: #cccccc; + } +.error + { + color: #B82619; + } +.err + { + color: #B82619; + } + +/* unordered list without bullets */ +ul.sans + { + list-style-type: none; + } + diff --git a/doc/en/Makefile b/doc/en/Makefile new file mode 100644 index 0000000..1d300c0 --- /dev/null +++ b/doc/en/Makefile @@ -0,0 +1,7 @@ + +index.html: PerlQt.pod + pod2html --css ../css/pod.css PerlQt.pod > index.html + perl -pi -e 's/cgibin/cgi-bin/' index.html + perl -pi -e 's/#http/http/g' index.html + rm -f pod2*~~ + diff --git a/doc/en/PerlQt.pod b/doc/en/PerlQt.pod new file mode 100644 index 0000000..b05a0a9 --- /dev/null +++ b/doc/en/PerlQt.pod @@ -0,0 +1,1147 @@ + +=head1 Programming PerlQt + +B<Germain Garand> + +This document describes a set of Perl bindings for the Qt toolkit. Contact +the author at <[email protected]> + +=head1 Introduction + +PerlQt-3 is Ashley Winters' full featured object oriented interface to +L<Trolltech|"http://www.trolltech.com">'s C++ Qt toolkit v3.0. + +It is based on the +L<SMOKE|"http://webcvs.kde.org/cgi-bin/cvsweb.cgi/kdebindings/smoke"> +library, a language independent low-level wrapper generated from Qt headers by +Richard Dale's +L<kalyptus|"http://webcvs.kde.org/cgi-bin/cvsweb.cgi/kdebindings/kalyptus"> +thanks to David Faure's module. + +This document describes the principles of PerlQt programming. +It assumes you have some basic Perl Object Oriented programming knowledge. + +Some C++ knowledge is recommended but not required. +It would mostly help you to find your way through L<Qt's +excellent documentation|"http://doc.trolltech.com"> which is our +ultimate and only reference. +If Qt is installed on your system, then you most probably +also have its documentation. Try the C<$QTDIR/bin/assistant> program. + + +=head1 Installation + +=head2 Requirements + +To compile and use PerlQt, you'll need : + +=over 4 + +=item * + +a POSIX system + +=item * + +GNU tools : automake(>=1.5), autoconf (>=2.13), aclocal... + +=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"> +The SMOKE library (Scripting Meta Object Kompiler) is part of L<KDE|"http://www.kde.org">'s B<kdebindings> module. +You may want to check if a precompiled version of this module exists for your +system. +PerlQt is packaged with its own copy, so you don't need to check it out. + +=back + +Perl and Qt's installation is out of the scope of this document. Please refer +to those projects' documentation. + +=head2 Compilation + +PerlQt uses GNU's Autoconf framework. However, the standard ./configure script is preferably driven +by the Makefile.PL wrapper. All options are forwarded to ./configure : + + perl Makefile.PL + +If SMOKE is missing, C<configure> will generate its sources. +Then : + + make + + make install + +This will install PerlQt, Puic and Smoke (if needed), as well as the pqtsh and pqtapi utilities. + +The preferred install location for SMOKE and Puic is in the KDE3 file system. +If you don't have KDE3 installed, specify a location with C<configure>'s +C<--prefix> option. e.g: + + perl Makefile.PL --prefix=/usr + +=head2 Troubleshooting and Configure Options + +If Smoke's linking fails or your Qt library was built with very specific +options, run Makefile.PL again with: + + perl Makefile.PL --with-threshold=0 + +When building smoke, configure will check for OpenGL and try to compile +support for it if it is properly installed and supported by Qt. + +You may disable this checking with: + + --disable-GL + +Also, default behaviour is to prefer the Mesa GL library over a proprietary +implementation. +If your system features a proprietary OpenGL library, and you'd like to use +it, specify: + + --without-Mesa + +=head2 How to install PerlQt with user rights + +To install PerlQt without super-user rights, simply follow this procedure: + +=over 4 + +=item * + +Perform a normal configuration, specifying as prefix a directory where you have write permissions : + + perl Makefile.PL --prefix=~ + +The above would install the Smoke library in ~/lib and the puic binary in ~/bin + +=item * + +Reconfigure the Perl module so that it doesn't target the standard perl hierarchy: + + cd PerlQt + perl Makefile.PL PREFIX=~ + cd .. + +Beware : this is not the same Makefile.PL as above, but the one located in the ./PerlQt +subdirectory + +=item * + +Compile and Install + + make && make install + +In order to use such an installation, you must tell to Perl where to find this extern hierarchy. +This can be done either on the command line: + + perl -Mlib="~/local/lib/perl/5.x.x" program.pl + +or at the top of your program: + + use lib qw( ~/local/lib/perl/5.x.x ); + +"5.x.x" should be changed to whatever Perl version your system is running. + +=back + +=head1 Anatomy of PerlQt + +A typical Qt program using GUI components is based on an event loop. + +This basically means that such a program is no more envisioned as a straight +flow where you would need to handle yourself every single events (such as a +mouse click or a key press). + +Instead, you just create an B<Application> object, create the GUI components it +uses, +define what objects methods need to be called when an event occurs, +and then start the main event loop. + +That's all! +Qt will handle all events and dispatch them to the correct subroutine. + +Lets see how this process is implemented in a minimal PerlQt program. + +=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> + +This program first loads the Qt interface [line 1] and creates the application +object, passing it a reference to the command line arguments array C<@ARGV> +[l.2]. +This application object is unique, and may later be accessed from +anywhere through the B<Qt::app()> pointer. + +At line 3, we create a PushButton, which has no parent (i.e : it won't be +contained nor owned by another widget). +Therefore, we pass to the constructor an B<undef> value for the parent argument, +which is PerlQt's way of passing a Null pointer. + +After some layouting at [l.4], we tell the application object that our main +widget is this PushButton [l.5]... that way, it will know that closing the +window associated with this widget means : I<quit the application>. + +Now the last steps are to make this widget visible (as opposed to +hidden, which is the default) by calling the B<show> method on it [l.6] and +to start the application loop [l.7]. + +B<Syntax elements summary :> + +=over 4 + +=item 1 + +All Qt classes are accessed through the prefix B<Qt::>, which replaces the +initial B<Q> of Qt classes. +When browsing the L<Qt +documentation|"http://doc.trolltech.com>, you simply need to change the +name of classes so that B<QFoo> reads B<Qt::Foo>. + +=item 2 + +An object is created by calling the B<constructor> of the class. It has the +same name as the class itself. + +You don't need to say C<new Qt::Foo> or C<Qt::Foo-E<gt>new()> as most Perl +programmers would have expected. + +Instead, you just say : + + my $object = Qt::<classname>(arg_1, ..., arg_n); + + +If you don't need to pass any argument to the constructor, simply say : + + my $object = Qt::<classname>; + + +=item 3 + +Whenever you need to pass a Null pointer as an argument, use Perl's B<undef> +keyword. Do not pass zero. + Beware: this is by far the most common error in PerlQt programs. + +Pointers are arguments preceded by an B<*> +character in Qt's documentation (e.g: "C<QWidget * widget>"). + +=back + +=head2 Inheritance and Objects + +Before we can discuss how Perl subroutines can be called back from Qt, we need +to introduce PerlQt's inheritance mechanism. + +PerlQt was designed to couple as tightly as possible Qt's simplicity and Perl's +power and flexibility. + +In order to achieve that goal, the classical Object Oriented Perl paradigm had +to be extended, much in the same way than Qt itself +had to extend C++'s paradigm with B<metaobjects>. + +=head3 A Custom Widget + +Lets rewrite the "Hello World!" program, this time using a custom version +of 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; + +Here, we want to create our own version of the PushButton widget. +Therefore, we create a new package for it [l.3] and import Qt [l.4]. + +We now want to declare our widget as subclassing PushButton. +This is done through the use of the C<Qt::isa> pragma [l.5], which accepts a +list of one or more parent Qt classes. + +It is now time to create a B<constructor> for our new widget. +This is done by creating a subroutine called B<NEW> I<(note the capitalized +form, which differentate it from the usual "new" constructor. PerlQt's NEW +constructor is called >B<implicitly>I< as can be seen on line 21)>. + +Since we want our widget to call its parent's constructor first, we call the +B<superclass's constructor> (here: Qt::PushButton) on line 9, passing it all +arguments we received. + +At this time, a class instance has been created and stored into a special +object holder named B<this> (not C<$this> but really just C<this>). + +Each time you invoke a method from within your package, you may now +indifferently say C<method()> or C<this-E<gt>method()>; + +=head3 Using Attributes + +When building a new composite widget, you may just create its different +parts inside B<my> variables, since widgets are only deleted by their parents +and not necessarily when their container goes out of scope. + +In other words, PerlQt performs clever reference counting to prevent +indesirable deletion of objects. + +Now, you'll often want to keep an access to those parts from anywhere inside +your package. +For this purpose, you may use the B<this> object's blessed hash, as is usual in Perl, +but that isn't really convenient and you don't have any compile time +checking... + +Here come B<Attributes>. Attributes are data holders where you can +store any kind of properties for your object. + +Declaring new attributes is done through the C<use Qt::attributes> pragma, as is +demonstrated in the following package implementation : + + 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 = " Foo "; + 17: } + 18: + 19: sub resizeEvent + 20: { + 21: setText( "w: ". width() ." h: ". height() . + 22: "\nt: ". itsTime->elapsed . pData ); + 23: } + 24: + 25: 1; + +=for html +<br/> +<div class='image'><img src="../images/ex2.png"/></div> + + +An attribute itsTime is declared at line 7, and loaded with a C<Qt::Time> object +at line 14. + +Since we reimplement the virtual function "resizeEvent" [l.19]. +each time the main widget is resized, this function will be triggered and +our Button's text updated with values coming from the object [l.21] and from the +attributes we defined [l.22]. + +B<Recapitulation> + +=over 4 + +=item * + +In order to inherit a Qt class, a package must contain a +C<use Qt::isa> pragma. +e.g: + + use Qt::isa "Qt::widget"; + +=item * + +The object constructor is named B<NEW> and is implicitly called. +Thus you should not say : + + my $o = MyButton->NEW("Hello"); + +But say : + + my $o = MyButton("Hello"); + +=item * + +Within a package, the current instance can be accessed through the B<this> +variable. + +When a member function is called, arguments are loaded as usual in the B<@_> +array, but B<without> the object pointer itself. + +Hence, you shouldn't say : + + sub myMember + { + my $self = shift; + my $arg = shift; + $arg->doThat($self); + $self->doIt; + } + +But : + + sub myMember + { + my $arg = shift; + $arg->doThat(this); + doIt; + } + +Furthermore, if you want to call a base class method from a derived class, +you'd use the specal attribute SUPER : + + sub example + { + print "Now calling the base class\n"; + SUPER->example(@_) + } + +Note that the : + + this->SUPER::Example(@_); + +construct is also available, but will pass the object as first argument. + + +=item * + +Whenever you need to store a contained object in your package, you may define it +as an B<Attribute> : + + use Qt::attributes qw( + firstAttribute + ... + lastAttribute); + +and then use it as a convenient accessor : + + firstAttribute = myContainedWidget( this ); + firstAttribute->resize( 100, 100 ); + +=item * + +To reimplement a B<virtual function>, simply create a B<sub> with the +same name in your object. + +Existing virtual functions are marked as such in Qt's documentation +(they are prefixed with the "virtual" keyword). + +You can inspect what virtual function names are being called by Qt at runtime by +putting a C<use Qt::debug qw( virtual )> statement at the top of your program. + +=back + +=head2 Signals and Slots + +We'll now learn how Qt objects can communicate with each other, +allowing an event occuring, for instance, in a given widget to trigger the +execution of one or several subroutines anywhere inside your program. + +Most other toolkits use callbacks for that purpose, but Qt has a much more +powerful and flexible mechanism called B<Signals and Slots>. + +Signals and slots are used for communication between objects. + +This can be thought off as something similar to the wiring between several Hi-fI +components : an amplificator, for instance, has a set of output signals, wich are +emitted wether a listening device is connected to them or not. Also, a tape +recorder deck can start to record when it receives a signal wired to it's input +slot, and it doesn't need to know that this signal is also received by a CD +recorder device, or listened through headphones. + +A Qt component behaves just like that. It has several output B<Signals> and +several input B<Slots> - and each signal can be connected to an unlimited number +of listening slots of the same type, wether they are inside or outside the +component. + +The general syntax of this connection process is either : + +Qt::Object::connect( sender, SIGNAL 'mysignal(arg_type)', +receiver, SLOT 'myslot(arg_type)'); + +or + +myObject->connect( sender, SIGNAL 'mysignal(arg_type)', SLOT +'myslot(arg_type)'); + +This mechanism can be extended at will by the declaration of custom Signals and +Slots, through the C<use Qt::signals> and C<use Qt::slots> pragma +(see also the other syntax, later on). + +Each declared slot will call the corresponding subroutine in your object, +each declared signal can be raised through the B<emit> keyword. + +B<As an example, lets rewrite again our Button package :> + + 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: wasClicked => [], + 9: change => ['int', 'int']; + 10: use Qt::signals + 11: changeIt => ['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 'wasClicked()'); + 19: this->connect(this, SIGNAL 'changeIt(int,int)', SLOT 'change(int,int)'); + 20: } + 21: + 22: sub wasClicked + 23: { + 24: my $w = width(); + 25: my $h = height(); + 26: setText( "w: $w h: $h\nt: ". itsTime->elapsed ); + 27: emit changeIt($w, $h); + 28: } + 29: + 30: sub change + 31: { + 32: my ($w, $h) = @_; + 33: print STDERR "w: $w h: $h \n"; + 34: } + 35: + 36: 1; + +In this package, we define two extra slots and one extra signal. + +We know from the Qt Documentation that a clicked PushButton emits a C<clicked()> +signal, so we connect it to our new slot at line 18. + +We also connect our signal C<changeIt> to our own C<change> slot- which is +quite stupid, but as an example. + +Now, whenever our Button is clicked, the C<clicked()> signal is raised and +triggers the C<wasClicked()> slot. C<wasClicked> then proceeds to emit +the C<changeIt(int,int)> signal [l.27], hence triggering the C<change(int,int)> +slot with two arguments. + +Finally, since PerlQt-3.008, an alternative syntax can be used to declare Signals and Slots: + + sub a_slot : SLOT(int, QString) + { + $int = shift; + $string = shift; + # do something + } + +and + + sub a_signal : SIGNAL(QString); + +This syntax is perfectly compatible with the traditional +C<use Qt::signals> and C<use Qt::slots> declarations. + +Eventually, it can prove good programming practice to mix both syntaxes, by first declaring +Signals/Slots with C<use Qt::slots/signals>, then repeat this declaration +in the actual implementation with the second syntax. + +Declarations will be checked for consistency at compile time, and any mismatch +in arguments would trigger a warning. + +=head1 RAD prototyping with Qt Designer and Puic + +=head2 Introduction + +=over 4 + +=item * Note: + +As of PerlQt-3.008, a separate PerlQt plugin for Qt Designer is available, +bringing full integration, syntax highlighting, code completion and allowing to run/debug your PerlQt project +entirely from the Designer GUI. +Nevertheless, the below is still accurate with regard to puic command line interaction +and with regard to using Qt Designer I<without> the specific plugin. + +=back + +As efficient and intuitive as Qt can be, building a complete GUI from scratch +is often a tedious task. + +Hopefully, Qt comes with a very sophisticated GUI Builder named Qt +Designer, which is close to a complete integrated development environment. +It features Project management, drag'n drop GUI building, a complete object +browser, graphical interconnection of signals and slots, and much much more. + +Qt Designer's output is XML which can be parsed by several command line tools, +among whose is B<puic> (the PerlQt User Interface Compiler). + +Assuming you have already built an interface file with the Designer, +translating it to a PerlQt program is simply a matter of issuing +one command : + + puic -x -o program.pl program.ui + +This will generate the package defined in your ui file and a basic main package +for testing purposes. + +You may prefer : + + puic -o package.pm program.ui + +This will only generate the package, which can then be used by a separate +program. + +=head2 Embedding Images + +If you need to B<embed images or icons>, it can be done in two ways +: + +=over 4 + +=item * Inline embedding + +For this, you need to check the "Edit->Form Settings->Pixmaps->Save inline" +checkbox inside Qt Designer. +Then : puic -x -o F<program.pl> F<program.ui> + +=item * Image Collection + +This option is more complex but also far more powerful and clean. + +puic -o F<Collection.pm> -embed F<unique_identifier> F<image-1> ... F<image-n> + +Then add a C<use Collection.pm> statement to your program's main package. + +If you've created a project file in Qt Designer, and added all images +you want to group (through "Project->Image Collection"), you'll find all those +images inside the directory where your project file (*.pro) is stored, under +/images. +You can then generate the corresponding image collection by issuing : + +puic -o F<Collection.pm> -embed F<identifier> ../images/* + +You can use as many image collections as you want in a program. Simply add a +B<use> statement for each collection. + +=back + +=head2 Working With B<.ui> Files + +It will often happen that you need to regenerate your user interface -either +because you changed your initial design, or you want to extend it. +Thus writing your program's code straight in the auto-generated Perl file is +quite a bad idea. +You'd run constantly the risk of overwriting your handcrafted code, or end +up doing lot of copy-paste. + +Instead, you may : + +=over 4 + +=item * Write slots implementation in the Designer + +In Qt Designer, select the I<Source> tab of the B<Object Explorer>. +There you can see a tree-like representation of your classes. +Now if you double-click on the I<Slots/public> entry, +you are prompted with a dialog where you can create a new custom slot for +your module. +Once this is done, the new slot appear inside the B<Object Explorer> tree and +clicking on it will bring you to a B<E<lt>Your ClassE<gt>.ui.h> file where you can write +the actual implementation of your slot. + +Keeping all the defaults, it should look like this : + + void Form1::newSlot() + { + + } + +The slot declaration is actually C++ code, but simply ignore it and write +your Perl code straight between the two braces, paying special attention to +indent it at least by one space. + + void Form1::newSlot() + { + print STDERR "Hello world from Form1::newSlot(); + if(this->foo()) + { + # do something + } + } + +All Perl code written this way will be saved to the ui.h file, and B<puic> will take care of +placing it back in the final program. + +Here, after running B<puic> on the Form1.ui file, you'd have: + + sub newSlot + { + print STDERR "Hello world from Form1::newSlot(); + if(this->foo()) + { + # do something + } + } + +=item * Subclassing your GUI + +By using B<puic>'s I<-subimpl> option, you may generate a derived module +inheriting your original user interface. + +You'd typically generate the derived module once, and write any handcrafted +code in this child. +Then, whenever you need to modify your GUI module, simply regenerate the +parent module, and your child will inherit those changes. + +To generate the base module : + + puic -o Form1.pm form1.ui + +(do this as often as needed, never edit by hand) + +To generate the child : + + puic -o Form2.pm -subimpl Form2 form1.ui + +or + + puic -o program.pl -x -subimpl Form2 form1.ui + +(do this once and work on the resulting file) + +=back + +=head1 More development tools + +PerlQt comes bundled with two simple programs that can help you to find your way through +the Qt API: + +=head2 pqtapi + +pqtapi is a commandline driven introspection tool. + + usage: pqtapi [-r <re>] [<class>] + + options: + -r <re> : find all functions matching regular expression/keyword <re> + -i : together with -r, performs a case insensitive search + -v : print PerlQt and Qt versions + -h : print this help message + +e.g: + + $>pqtapi -ir 'setpoint.* int' + void QCanvasLine::setPoints(int, int, int, int) + void QPointArray::setPoint(uint, int, int) + +=head2 pqtsh + +B<pqtsh> is a graphical shell that can be used to test the API interactively. +It is fairly self explanatory and includes an interactive example (C<Help-E<gt>Example>) + +=for html +<br/> +<div class='image'><img src="../images/pqtsh.png"/></div> + +=head1 Known Limitations + +Templated classes aren't available yet (classes derived from templated classes are). + +=head1 Credits + +PerlQt-3 is (c) 2002 Ashley Winters (and (c) 2003 Germain Garand) + +Kalyptus and the Smoke generation engine are (c) David Faure and Richard Dale + +Puic is (c) TrollTech AS., Phil Thompson and Germain Garand, + +The mentioned software is released under the GNU Public Licence v.2 or later. + + +=head1 Appendix 1 : C++ conventions and their Perl counterpart + +Whenever you want to use a class/method described in Qt's +L<documentation|"http://doc.trolltech.com"> (see also the 'assistant' program bundled with Qt) +from PerlQt, you need to follow some simple translation rules. + +=over 4 + +=item Classnames + +=over 4 + +=item * + +All classnames are changed from a B<Q> prefix in Qt to a B<Qt::> prefix +in Perl. +e.g: QComboBox is named Qt::ComboBox within PerlQt. + +=back + +=item Functions + +=over 4 + +=item * + +Functions referenced as B<static> are accessed directly, and not through +an object. Thus the static function Foo in class QBar would be accessed from +PerlQt as + + Qt::Bar::Foo( arg-1,...,arg-n); + +The only notable exceptions are : + + qApp() will map to Qt::app() + qVersion() will map to Qt::version() # not really needed anymore: we have qVersion(). See Global Functions below. + +=item * + +Functions referenced as B<members> or B<Signals> are accessed through an object +with the B<-E<gt>> operator. +e.g: + + $widget->show; + +There are no fundamental differences between methods and signals, however PerlQt +provides the B<emit> keyword as a convenient mnemonic, so that it is clear you +are emitting a signal : + + emit $button->clicked; + +=back + +=item Arguments + +=over 4 + +=item * By value + +When an argument isn't preceded by the B<&> or B<*> character, it is passed by +value. For all basic types such as int, char, float and double, PerlQt will +automatically convert litteral and scalar values to the corresponding C++ type. + +Thus for a constructor prototype written as follow in the documentation : + + QSize ( int w, int h ) + + +You'd say : + + Qt::Size(8, 12); + + +=item * By reference + +When an argument is preceded by the B<&> character, it means a reference to an +object or to a type is expected. You may either provide a variable name or a +temporary object : + + $keyseq = Qt::keySequence( &Qt::CTRL + &Qt::F3 ); + $widget->setAccel( $keyseq ); + +or + + $widget->setAccel(Qt::keySequence( &Qt::CTRL + &Qt::F3 ); + +If the argument isn't qualified as B<const> (constant), it means the passed +object may be altered during the process - you must then provide a variable. + +=item * By pointer + +When an argument is preceded by the B<*> character, it means a +pointer to an object or to a type is expected. You may provide a variable +name or the Perl B<undef> keyword for a Null pointer. + +Similarly, if the argument isn't B<const>, the passed object may be altered by +the method call. + +=back + +=item Enumerations + +Enumerations are sort of named aliases for numeric values that would be hard to +remember otherwise. + +A C++ example would be : + + enum Strange { Apple, Orange, Lemon } + +where C<Strange> is the generic enumeration name, and C<Apple>, C<Orange>, +C<Lemon> its possible values, which are only aliases for numbers (here 0, 1 +and 2). + +Access to enumerations values in Perl Qt is very similar to a static function +call. In fact, it B<is> a static function call. + +Therefore, since you probably want to avoid some readability problems, we +recommend the use of the alternate function call syntax : C<&function>. + +Lets now go back to our C<Strange> example. + +If its definition was encountered in the class C<QFruits>, you'd write from +PerlQt : + + $apple_plus_orange = &Qt::Fruit::Apple + &Qt::Fruit::Orange; + +=item Operators + +Within PerlQt, B<operators overloading> works transparently. +If a given operator is overloaded in a Qt class (which means using it triggers a custom method) +it will behave identically in PerlQt. +Beware though that due to limitations of the Smoke binding library, not all overloaded operators are +available in PerlQt. +You can check the availability of a given operator by using the pqtapi program. +Also, due to outstanding differences between C++'s and Perl's object paradigm, the copy constructor operator (a.k.a '=') +has been disabled. + +e.g-1: '+=' overload + + $p1 = Qt::Point(10, 10) + $p2 = Qt::Point(30,40) + $p2 += $p1; # $p2 becomes (40,50) + +e.g-2: '<<' overload + + $f = Qt::File("example"); + $f->open( IO_WriteOnly ); # see 'Constants' below + $s = Qt::TextStream( $f ); + $s << "What can I do with " << 12 << " apples?"; + +=item Constants + +Qt doesn't use many constants, but there is at least one place where they are used : for setting +Input/Output flags on files. +In order to avoid the namespace pollution induced by global constants, PerlQt group them in the B<Qt::constants> module. +For instance, requesting the importation of all IO constants into the current namespace would be done with: + + use Qt::constants; + +You may also import specific symbols: + + use Qt::constants qw( IO_ReadOnly IO_WriteOnly ); + +=item Global Functions + + +Qt has also some utilitarian functions such as bitBlt, qCompress, etc. + +Those were global scope functions and have been grouped in a common namespace: +C<Qt::GlobalSpace>. + +Hence, you shall access this namespace either with a fully qualified call: + + Qt::GlobalSpace::qUncompress( $buffer ) + +Or directly, after importation in the current namespace: + + use Qt::GlobalSpace; + qUncompress( $buffer ) + +Of course, you may selectively import a few functions: + + use Qt::GlobalSpace qw( qUncompress bitBlt ) + +B<Note:> GlobalSpace has also operators, such has the one performing an addition on two +Qt::Point(). Those operators are called automatically. + +e.g: + + $p1 = Qt::Point(10, 10) + Qt::Point(20, 20) + +=back + + +=head1 Appendix 2 : Internationalization + +PerlQt handles internationalization by always converting B<QString> back to B<utf8> in Perl. + +Conversions from Perl strings to QStrings are made according to context : + +=over 4 + +=item * If the Perl string is already utf8-encoded + +then the string will be converted straight to QString. + +This is the most convenient and seemless way of internationalizing your application. Typically, one would just enable +the use of utf8 in source code with the C<use utf8> pragma and write its application with an utf8 aware editor. + +=item * If the string isn't tagged as utf8, and the B<use locale> pragma is not set + +then the string will be converted to QString's utf8 from B<ISO-Latin-1>. + +=item * If the string isn't tagged as utf8 and the B<use locale> pragma is set + +then the string will be converted to QString's utf8 according to the currently set B<locale>. + +=back + +Once a string contains utf8, you can convert it back to any locale by setting up B<converters> : + + $tr1=Qt::TextCodec::codecForLocale(); # this one will use current locale + $tr2=Qt::TextCodec::codecForName("KOI8-R"); # that one forces a specific locale (Russian) + + print $tr1->fromUnicode(Qt::DateTime::currentDateTime()->toString)."\n\n"; + print $tr2->fromUnicode($my_utf8_string); + +Or, with Perl >= 5.8.0, you may use Perl's B<Encode> modules (see C<perldoc Encode>). + +=head3 disabling utf-8 + +Developers who don't want to use UTF-8 or want to temporarily disable UTF-8 marshalling +for handling legacy programs may use the B<use bytes> pragma (and the corresponding B<no bytes>). + +Within the scope of this pragma, QStrings are marshalled back to ISO-Latin1 (default) or to your locale +(if B<use locale> has been set). + +Frivole use of this pragma is strongly discouraged as it ruins worldwide standardization efforts. + +=head1 Appendix 3 : Debugging Channels + +The B<Qt::debug> module offers various debugging channels/features. + + use Qt::debug; + + use Qt::debug qw|calls autoload verbose|; + +With the simple C<use Qt::debug> statement, the B<verbose> and B<ambiguous> channels are activated. +If you specify a list of channels within the use statement, then only the specified channels will be enabled. + +B<Available channels :> + +=over 4 + +=item * ambiguous + +Check if method and function calls are ambiguous, and tell which of the alternatives +was finally elected. + +=item * verbose + +Enable more verbose debugging. + +Together with B<ambiguous>, tell you the nearest matches in case +a method or function call fails. +e.g: + + use Qt; + use Qt::debug; + $a= Qt::Application(\@ARGV); + $a->libraryPath("foo"); + + --- No method to call for : + QApplication::libraryPath('foo') + 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 + +For every call, tell what corresponding Qt method is called +(detailing the arguments if B<verbose> is on). + +=item * autoload + +Track the intermediate code between a method invocation in Perl +and its resolution to either a Qt or Perl call. + +=item * gc + +Give informations about garbage collection +whenever a Qt object is deleted and/or a Perl object is destroyed + +=item * virtual + +Report whenever a virtual function tries to access its Perl +reimplementation (wether it exists or not). + +=item * all + +Enable all channels + +=back + + +=head1 Appendix 4 : Marshallers + +A marshaller is a piece of "glue code" translating a given datatype to another. + +Within PerlQt, most Qt objects keep their object nature, so that one may invoke methods on them. +However, some classes and datatypes map so naturally to some Perl types that keeping their object nature would +would feel unnatural and clumsy. + +For instance, instead of returning a Qt::StringList object, which would require an iterator to retrieve its content, +PerlQt will translate it to an array reference containing all the object's strings. + +In the other way, instead of providing a Qt::StringList object as an argument of a method, one would simply +provide the reference to an array of Perl strings. + +Here is the list of Marshallers as of PerlQt-3.008 : + + ----------------------------------------------------------------- + float, double <=> Perl real (NV) + char, uchar, int, uint, enum + long, ulong, short, ushort <=> Perl integer (IV) + QString, -&, -* => Perl string (utf8) + QString, -&, -* <= Perl string (utf8 or iso-latin1 or locale) + QCString, -&, -* <=> Perl string (utf8 or bytes, according to content or "bytes" pragma) + QByteArray, -&, -* <=> Perl string (bytes) + QStringList, -&, -* => Reference to an array of Perl strings (utf8) + QString, -&, -* => Perl string (utf8 or iso-latin1 or locale) + int&, -* <=> Perl integer (IV) + bool&, -* <=> Perl boolean + char* <=> Perl string (bytes) + char** <= Reference to an array of Perl strings (bytes) + uchar* <= Perl string (bytes) + QRgb* <= Reference to an array of Perl integers (IV) + QCOORD* <= Reference to an array of Perl integers (IV) + void* <=> Reference to a Perl integer (IV) + QValueList<int>, - *, - & <=> Reference to an array of Perl integers (IV) + QCanvasItemList, - *, - & => Reference to an array of Qt::CanvasItem + QWidgetList, - *, - & <=> Reference to an array of Qt::Widget + QObjectList, - *, - & <=> Reference to an array of Qt::Object + QFileInfoList, - *, - & <=> Reference to an array of Qt::FileInfo + QPtrList<QTab>, - *, - & <=> Reference to an array of Qt::Tab + QPtrList<QToolBar>, - *, - & <=> Reference to an array of Qt::ToolBar + QPtrList<QNetworkOperation>, - *, - & <=> Reference to an array of Qt::NetworkOperation + QPtrList<QDockWindow>, - *, - & <=> Reference to an array of Qt::DockWindow + (QUObject*) + + + + + diff --git a/doc/en/index.html b/doc/en/index.html new file mode 100644 index 0000000..6a4cc7b --- /dev/null +++ b/doc/en/index.html @@ -0,0 +1,1081 @@ +<!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>Programming 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="#programming_perlqt">Programming PerlQt</a></li> + <li><a href="#introduction">Introduction</a></li> + <li><a href="#installation">Installation</a></li> + <ul> + + <li><a href="#requirements">Requirements</a></li> + <li><a href="#compilation">Compilation</a></li> + <li><a href="#troubleshooting_and_configure_options">Troubleshooting and Configure Options</a></li> + <li><a href="#how_to_install_perlqt_with_user_rights">How to install PerlQt with user rights</a></li> + </ul> + + <li><a href="#anatomy_of_perlqt">Anatomy of PerlQt</a></li> + <ul> + + <li><a href="#hello_world">Hello World</a></li> + <li><a href="#inheritance_and_objects">Inheritance and Objects</a></li> + <ul> + + <li><a href="#a_custom_widget">A Custom Widget</a></li> + <li><a href="#using_attributes">Using Attributes</a></li> + </ul> + + <li><a href="#signals_and_slots">Signals and Slots</a></li> + </ul> + + <li><a href="#rad_prototyping_with_qt_designer_and_puic">RAD prototyping with Qt Designer and Puic</a></li> + <ul> + + <li><a href="#introduction">Introduction</a></li> + <li><a href="#embedding_images">Embedding Images</a></li> + <li><a href="#working_with_.ui_files">Working With <strong>.ui</strong> Files</a></li> + </ul> + + <li><a href="#more_development_tools">More development tools</a></li> + <ul> + + <li><a href="#pqtapi">pqtapi</a></li> + <li><a href="#pqtsh">pqtsh</a></li> + </ul> + + <li><a href="#known_limitations">Known Limitations</a></li> + <li><a href="#credits">Credits</a></li> + <li><a href="#appendix_1_:_c++_conventions_and_their_perl_counterpart">Appendix 1 : C++ conventions and their Perl counterpart</a></li> + <li><a href="#appendix_2_:_internationalization">Appendix 2 : Internationalization</a></li> + <ul> + + <ul> + + <li><a href="#disabling_utf8">disabling utf-8</a></li> + </ul> + + </ul> + + <li><a href="#appendix_3_:_debugging_channels">Appendix 3 : Debugging Channels</a></li> + <li><a href="#appendix_4_:_marshallers">Appendix 4 : Marshallers</a></li> +</ul> +<!-- INDEX END --> + +<hr /> +<p> +</p> +<h1><a name="programming_perlqt">Programming PerlQt</a></h1> +<p><strong>Germain Garand</strong></p> +<p>This document describes a set of Perl bindings for the Qt toolkit. Contact +the author at <<a href="mailto:[email protected]">[email protected]</a>></p> +<p> +</p> +<hr /> +<h1><a name="introduction">Introduction</a></h1> +<p>PerlQt-3 is Ashley Winters' full featured object oriented interface to +<a href="http://www.trolltech.com">Trolltech</a>'s C++ Qt toolkit v3.0.</p> +<p>It is based on the +<a href="http://webcvs.kde.org/cgi-bin/cvsweb.cgi/kdebindings/smoke">SMOKE</a> +library, a language independent low-level wrapper generated from Qt headers by +Richard Dale's +<a href="http://webcvs.kde.org/cgi-bin/cvsweb.cgi/kdebindings/kalyptus">kalyptus</a> +thanks to David Faure's module.</p> +<p>This document describes the principles of PerlQt programming. +It assumes you have some basic Perl Object Oriented programming knowledge.</p> +<p>Some C++ knowledge is recommended but not required. +It would mostly help you to find your way through <a href="http://doc.trolltech.com">Qt's excellent documentation</a> which is our +ultimate and only reference. +If Qt is installed on your system, then you most probably +also have its documentation. Try the <code>$QTDIR/bin/assistant</code> program.</p> +<p> +</p> +<hr /> +<h1><a name="installation">Installation</a></h1> +<p> +</p> +<h2><a name="requirements">Requirements</a></h2> +<p>To compile and use PerlQt, you'll need :</p> +<ul> +<li></li> +a POSIX system +<p></p> +<li></li> +GNU tools : automake(>=1.5), autoconf (>=2.13), aclocal... +<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> +The SMOKE library (Scripting Meta Object Kompiler) is part of <a href="http://www.kde.org">KDE</a>'s <strong>kdebindings</strong> module. +You may want to check if a precompiled version of this module exists for your +system. +PerlQt is packaged with its own copy, so you don't need to check it out. +<p></p></ul> +<p>Perl and Qt's installation is out of the scope of this document. Please refer +to those projects' documentation.</p> +<p> +</p> +<h2><a name="compilation">Compilation</a></h2> +<p>PerlQt uses GNU's Autoconf framework. However, the standard ./configure script is preferably driven +by the Makefile.PL wrapper. All options are forwarded to ./configure :</p> +<pre> + perl Makefile.PL</pre> +<p>If SMOKE is missing, <code>configure</code> will generate its sources. +Then :</p> +<pre> + make</pre> +<pre> + make install</pre> +<p>This will install PerlQt, Puic and Smoke (if needed), as well as the pqtsh and pqtapi utilities.</p> +<p>The preferred install location for SMOKE and Puic is in the KDE3 file system. +If you don't have KDE3 installed, specify a location with <code>configure</code>'s +<code>--prefix</code> option. e.g:</p> +<pre> + perl Makefile.PL --prefix=/usr</pre> +<p> +</p> +<h2><a name="troubleshooting_and_configure_options">Troubleshooting and Configure Options</a></h2> +<p>If Smoke's linking fails or your Qt library was built with very specific +options, run Makefile.PL again with:</p> +<pre> + perl Makefile.PL --with-threshold=0</pre> +<p>When building smoke, configure will check for OpenGL and try to compile +support for it if it is properly installed and supported by Qt.</p> +<p>You may disable this checking with:</p> +<pre> + --disable-GL</pre> +<p>Also, default behaviour is to prefer the Mesa GL library over a proprietary +implementation. +If your system features a proprietary OpenGL library, and you'd like to use +it, specify:</p> +<pre> + --without-Mesa</pre> +<p> +</p> +<h2><a name="how_to_install_perlqt_with_user_rights">How to install PerlQt with user rights</a></h2> +<p>To install PerlQt without super-user rights, simply follow this procedure:</p> +<ul> +<li></li> +Perform a normal configuration, specifying as prefix a directory where you have write permissions : +<pre> + perl Makefile.PL --prefix=~</pre> +<p>The above would install the Smoke library in ~/lib and the puic binary in ~/bin</p> +<p></p> +<li></li> +Reconfigure the Perl module so that it doesn't target the standard perl hierarchy: +<pre> + cd PerlQt + perl Makefile.PL PREFIX=~ + cd ..</pre> +<p>Beware : this is not the same Makefile.PL as above, but the one located in the ./PerlQt +subdirectory</p> +<p></p> +<li></li> +Compile and Install +<pre> + make && make install</pre> +<p>In order to use such an installation, you must tell to Perl where to find this extern hierarchy. +This can be done either on the command line:</p> +<pre> + perl -Mlib="~/local/lib/perl/5.x.x" program.pl</pre> +<p>or at the top of your program:</p> +<pre> + use lib qw( ~/local/lib/perl/5.x.x );</pre> +<p>``5.x.x'' should be changed to whatever Perl version your system is running.</p> +<p></p></ul> +<p> +</p> +<hr /> +<h1><a name="anatomy_of_perlqt">Anatomy of PerlQt</a></h1> +<p>A typical Qt program using GUI components is based on an event loop.</p> +<p>This basically means that such a program is no more envisioned as a straight +flow where you would need to handle yourself every single events (such as a +mouse click or a key press).</p> +<p>Instead, you just create an <strong>Application</strong> object, create the GUI components it +uses, +define what objects methods need to be called when an event occurs, +and then start the main event loop.</p> +<p>That's all! +Qt will handle all events and dispatch them to the correct subroutine.</p> +<p>Lets see how this process is implemented in a minimal PerlQt program.</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>This program first loads the Qt interface [line 1] and creates the application +object, passing it a reference to the command line arguments array <code>@ARGV</code> +[l.2]. +This application object is unique, and may later be accessed from +anywhere through the <strong>Qt::app()</strong> pointer.</p> +<p>At line 3, we create a PushButton, which has no parent (i.e : it won't be +contained nor owned by another widget). +Therefore, we pass to the constructor an <strong>undef</strong> value for the parent argument, +which is PerlQt's way of passing a Null pointer.</p> +<p>After some layouting at [l.4], we tell the application object that our main +widget is this PushButton [l.5]... that way, it will know that closing the +window associated with this widget means : <em>quit the application</em>.</p> +<p>Now the last steps are to make this widget visible (as opposed to +hidden, which is the default) by calling the <strong>show</strong> method on it [l.6] and +to start the application loop [l.7].</p> +<p><strong>Syntax elements summary :</strong></p> +<ol> +<li></li> +All Qt classes are accessed through the prefix <strong>Qt::</strong>, which replaces the +initial <strong>Q</strong> of Qt classes. +When browsing the <a href="http://doc.trolltech.com">Qt documentation</a>, you simply need to change the +name of classes so that <strong>QFoo</strong> reads <strong>Qt::Foo</strong>. +<p></p> +<li></li> +An object is created by calling the <strong>constructor</strong> of the class. It has the +same name as the class itself. +<p>You don't need to say <code>new Qt::Foo</code> or <code>Qt::Foo->new()</code> as most Perl +programmers would have expected.</p> +<p>Instead, you just say :</p> +<pre> + my $object = Qt::<classname>(arg_1, ..., arg_n);</pre> +<p>If you don't need to pass any argument to the constructor, simply say :</p> +<pre> + my $object = Qt::<classname>;</pre> +<p></p> +<li></li> +Whenever you need to pass a Null pointer as an argument, use Perl's <strong>undef</strong> +keyword. Do not pass zero. + Beware: this is by far the most common error in PerlQt programs. +<p>Pointers are arguments preceded by an <strong>*</strong> +character in Qt's documentation (e.g: ``<code>QWidget * widget</code>'').</p> +<p></p></ol> +<p> +</p> +<h2><a name="inheritance_and_objects">Inheritance and Objects</a></h2> +<p>Before we can discuss how Perl subroutines can be called back from Qt, we need +to introduce PerlQt's inheritance mechanism.</p> +<p>PerlQt was designed to couple as tightly as possible Qt's simplicity and Perl's +power and flexibility.</p> +<p>In order to achieve that goal, the classical Object Oriented Perl paradigm had +to be extended, much in the same way than Qt itself +had to extend C++'s paradigm with <strong>metaobjects</strong>.</p> +<p> +</p> +<h3><a name="a_custom_widget">A Custom Widget</a></h3> +<p>Lets rewrite the ``Hello World!'' program, this time using a custom version +of 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>Here, we want to create our own version of the PushButton widget. +Therefore, we create a new package for it [l.3] and import Qt [l.4].</p> +<p>We now want to declare our widget as subclassing PushButton. +This is done through the use of the <code>Qt::isa</code> pragma [l.5], which accepts a +list of one or more parent Qt classes.</p> +<p>It is now time to create a <strong>constructor</strong> for our new widget. +This is done by creating a subroutine called <strong>NEW</strong> <em>(note the capitalized +form, which differentate it from the usual ``new'' constructor. PerlQt's NEW +constructor is called </em><strong>implicitly</strong><em> as can be seen on line 21)</em>.</p> +<p>Since we want our widget to call its parent's constructor first, we call the +<strong>superclass's constructor</strong> (here: Qt::PushButton) on line 9, passing it all +arguments we received.</p> +<p>At this time, a class instance has been created and stored into a special +object holder named <strong>this</strong> (not <code>$this</code> but really just <code>this</code>).</p> +<p>Each time you invoke a method from within your package, you may now +indifferently say <code>method()</code> or <code>this->method()</code>;</p> +<p> +</p> +<h3><a name="using_attributes">Using Attributes</a></h3> +<p>When building a new composite widget, you may just create its different +parts inside <strong>my</strong> variables, since widgets are only deleted by their parents +and not necessarily when their container goes out of scope.</p> +<p>In other words, PerlQt performs clever reference counting to prevent +indesirable deletion of objects.</p> +<p>Now, you'll often want to keep an access to those parts from anywhere inside +your package. +For this purpose, you may use the <strong>this</strong> object's blessed hash, as is usual in Perl, +but that isn't really convenient and you don't have any compile time +checking...</p> +<p>Here come <strong>Attributes</strong>. Attributes are data holders where you can +store any kind of properties for your object.</p> +<p>Declaring new attributes is done through the <code>use Qt::attributes</code> pragma, as is +demonstrated in the following package implementation :</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 = " Foo "; + 17: } + 18: + 19: sub resizeEvent + 20: { + 21: setText( "w: ". width() ." h: ". height() . + 22: "\nt: ". itsTime->elapsed . pData ); + 23: } + 24: + 25: 1;</pre> +<br/> +<div class='image'><img src="../images/ex2.png"/></div><p>An attribute itsTime is declared at line 7, and loaded with a <code>Qt::Time</code> object +at line 14.</p> +<p>Since we reimplement the virtual function ``resizeEvent'' [l.19]. +each time the main widget is resized, this function will be triggered and +our Button's text updated with values coming from the object [l.21] and from the +attributes we defined [l.22].</p> +<p><strong>Recapitulation</strong></p> +<ul> +<li></li> +In order to inherit a Qt class, a package must contain a +<code>use Qt::isa</code> pragma. +e.g: + +<pre> + + use Qt::isa "Qt::widget";</pre> +<p></p> +<li></li> +The object constructor is named <strong>NEW</strong> and is implicitly called. +Thus you should not say : +<pre> + my $o = MyButton->NEW("Hello");</pre> +<p>But say :</p> +<pre> + my $o = MyButton("Hello");</pre> +<p></p> +<li></li> +Within a package, the current instance can be accessed through the <strong>this</strong> +variable. +<p>When a member function is called, arguments are loaded as usual in the <strong>@_</strong> +array, but <strong>without</strong> the object pointer itself.</p> +<p>Hence, you shouldn't say :</p> +<pre> + sub myMember + { + my $self = shift; + my $arg = shift; + $arg->doThat($self); + $self->doIt; + } + +But :</pre> +<pre> + sub myMember + { + my $arg = shift; + $arg->doThat(this); + doIt; + }</pre> +<p>Furthermore, if you want to call a base class method from a derived class, +you'd use the specal attribute SUPER :</p> +<pre> + sub example + { + print "Now calling the base class\n"; + SUPER->example(@_) + }</pre> +<p>Note that the :</p> +<pre> + this->SUPER::Example(@_);</pre> +<p>construct is also available, but will pass the object as first argument.</p> +<p></p> +<li></li> +Whenever you need to store a contained object in your package, you may define it +as an <strong>Attribute</strong> : +<pre> + use Qt::attributes qw( + firstAttribute + ... + lastAttribute);</pre> +<p>and then use it as a convenient accessor :</p> +<pre> + firstAttribute = myContainedWidget( this ); + firstAttribute->resize( 100, 100 );</pre> +<p></p> +<li></li> +To reimplement a <strong>virtual function</strong>, simply create a <strong>sub</strong> with the +same name in your object. +<p>Existing virtual functions are marked as such in Qt's documentation +(they are prefixed with the ``virtual'' keyword).</p> +<p>You can inspect what virtual function names are being called by Qt at runtime by +putting a <code>use Qt::debug qw( virtual )</code> statement at the top of your program.</p> +<p></p></ul> +<p> +</p> +<h2><a name="signals_and_slots">Signals and Slots</a></h2> +<p>We'll now learn how Qt objects can communicate with each other, +allowing an event occuring, for instance, in a given widget to trigger the +execution of one or several subroutines anywhere inside your program.</p> +<p>Most other toolkits use callbacks for that purpose, but Qt has a much more +powerful and flexible mechanism called <strong>Signals and Slots</strong>.</p> +<p>Signals and slots are used for communication between objects.</p> +<p>This can be thought off as something similar to the wiring between several Hi-fI +components : an amplificator, for instance, has a set of output signals, wich are +emitted wether a listening device is connected to them or not. Also, a tape +recorder deck can start to record when it receives a signal wired to it's input +slot, and it doesn't need to know that this signal is also received by a CD +recorder device, or listened through headphones.</p> +<p>A Qt component behaves just like that. It has several output <strong>Signals</strong> and +several input <strong>Slots</strong> - and each signal can be connected to an unlimited number +of listening slots of the same type, wether they are inside or outside the +component.</p> +<p>The general syntax of this connection process is either :</p> +<p>Qt::Object::connect( sender, SIGNAL 'mysignal(arg_type)', +receiver, SLOT 'myslot(arg_type)');</p> +<p>or</p> +<p>myObject->connect( sender, SIGNAL 'mysignal(arg_type)', SLOT +'myslot(arg_type)');</p> +<p>This mechanism can be extended at will by the declaration of custom Signals and +Slots, through the <code>use Qt::signals</code> and <code>use Qt::slots</code> pragma +(see also the other syntax, later on).</p> +<p>Each declared slot will call the corresponding subroutine in your object, +each declared signal can be raised through the <strong>emit</strong> keyword.</p> +<p><strong>As an example, lets rewrite again our Button package :</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: wasClicked => [], + 9: change => ['int', 'int']; + 10: use Qt::signals + 11: changeIt => ['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 'wasClicked()'); + 19: this->connect(this, SIGNAL 'changeIt(int,int)', SLOT 'change(int,int)'); + 20: } + 21: + 22: sub wasClicked + 23: { + 24: my $w = width(); + 25: my $h = height(); + 26: setText( "w: $w h: $h\nt: ". itsTime->elapsed ); + 27: emit changeIt($w, $h); + 28: } + 29: + 30: sub change + 31: { + 32: my ($w, $h) = @_; + 33: print STDERR "w: $w h: $h \n"; + 34: } + 35: + 36: 1;</pre> +<p>In this package, we define two extra slots and one extra signal.</p> +<p>We know from the Qt Documentation that a clicked PushButton emits a <code>clicked()</code> +signal, so we connect it to our new slot at line 18.</p> +<p>We also connect our signal <code>changeIt</code> to our own <code>change</code> slot- which is +quite stupid, but as an example.</p> +<p>Now, whenever our Button is clicked, the <code>clicked()</code> signal is raised and +triggers the <code>wasClicked()</code> slot. <code>wasClicked</code> then proceeds to emit +the <code>changeIt(int,int)</code> signal [l.27], hence triggering the <code>change(int,int)</code> +slot with two arguments.</p> +<p>Finally, since PerlQt-3.008, an alternative syntax can be used to declare Signals and Slots:</p> +<pre> + sub a_slot : SLOT(int, QString) + { + $int = shift; + $string = shift; + # do something + }</pre> +<p>and</p> +<pre> + sub a_signal : SIGNAL(QString);</pre> +<p>This syntax is perfectly compatible with the traditional +<code>use Qt::signals</code> and <code>use Qt::slots</code> declarations.</p> +<p>Eventually, it can prove good programming practice to mix both syntaxes, by first declaring +Signals/Slots with <code>use Qt::slots/signals</code>, then repeat this declaration +in the actual implementation with the second syntax.</p> +<p>Declarations will be checked for consistency at compile time, and any mismatch +in arguments would trigger a warning.</p> +<p> +</p> +<hr /> +<h1><a name="rad_prototyping_with_qt_designer_and_puic">RAD prototyping with Qt Designer and Puic</a></h1> +<p> +</p> +<h2><a name="introduction">Introduction</a></h2> +<ul> +<li><strong><a name="item_note%3a">Note:</a></strong><br /> +</li> +As of PerlQt-3.008, a separate PerlQt plugin for Qt Designer is available, +bringing full integration, syntax highlighting, code completion and allowing to run/debug your PerlQt project +entirely from the Designer GUI. +Nevertheless, the below is still accurate with regard to puic command line interaction +and with regard to using Qt Designer <em>without</em> the specific plugin. +<p></p></ul> +<p>As efficient and intuitive as Qt can be, building a complete GUI from scratch +is often a tedious task.</p> +<p>Hopefully, Qt comes with a very sophisticated GUI Builder named Qt +Designer, which is close to a complete integrated development environment. +It features Project management, drag'n drop GUI building, a complete object +browser, graphical interconnection of signals and slots, and much much more.</p> +<p>Qt Designer's output is XML which can be parsed by several command line tools, +among whose is <strong>puic</strong> (the PerlQt User Interface Compiler).</p> +<p>Assuming you have already built an interface file with the Designer, +translating it to a PerlQt program is simply a matter of issuing +one command :</p> +<pre> + puic -x -o program.pl program.ui</pre> +<p>This will generate the package defined in your ui file and a basic main package +for testing purposes.</p> +<p>You may prefer :</p> +<pre> + puic -o package.pm program.ui</pre> +<p>This will only generate the package, which can then be used by a separate +program.</p> +<p> +</p> +<h2><a name="embedding_images">Embedding Images</a></h2> +<p>If you need to <strong>embed images or icons</strong>, it can be done in two ways +:</p> +<ul> +<li><strong><a name="item_inline_embedding">Inline embedding</a></strong><br /> +</li> +For this, you need to check the ``Edit->Form Settings->Pixmaps->Save inline'' +checkbox inside Qt Designer. +Then : puic -x -o <em>program.pl</em> <em>program.ui</em> +<p></p> +<li><strong><a name="item_image_collection">Image Collection</a></strong><br /> +</li> +This option is more complex but also far more powerful and clean. +<p>puic -o <em>Collection.pm</em> -embed <em>unique_identifier</em> <em>image-1</em> ... <em>image-n</em></p> +<p>Then add a <code>use Collection.pm</code> statement to your program's main package.</p> +<p>If you've created a project file in Qt Designer, and added all images +you want to group (through ``Project->Image Collection''), you'll find all those +images inside the directory where your project file (*.pro) is stored, under +/images. +You can then generate the corresponding image collection by issuing :</p> +<p>puic -o <em>Collection.pm</em> -embed <em>identifier</em> ../images/*</p> +<p>You can use as many image collections as you want in a program. Simply add a +<strong>use</strong> statement for each collection.</p> +<p></p></ul> +<p> +</p> +<h2><a name="working_with_.ui_files">Working With <strong>.ui</strong> Files</a></h2> +<p>It will often happen that you need to regenerate your user interface -either +because you changed your initial design, or you want to extend it. +Thus writing your program's code straight in the auto-generated Perl file is +quite a bad idea. +You'd run constantly the risk of overwriting your handcrafted code, or end +up doing lot of copy-paste.</p> +<p>Instead, you may :</p> +<ul> +<li><strong><a name="item_write_slots_implementation_in_the_designer">Write slots implementation in the Designer</a></strong><br /> +</li> +In Qt Designer, select the <em>Source</em> tab of the <strong>Object Explorer</strong>. +There you can see a tree-like representation of your classes. +Now if you double-click on the <em>Slots/public</em> entry, +you are prompted with a dialog where you can create a new custom slot for +your module. +Once this is done, the new slot appear inside the <strong>Object Explorer</strong> tree and +clicking on it will bring you to a <strong><Your Class>.ui.h</strong> file where you can write +the actual implementation of your slot. +<p>Keeping all the defaults, it should look like this :</p> +<pre> + void Form1::newSlot() + { + + }</pre> +<p>The slot declaration is actually C++ code, but simply ignore it and write +your Perl code straight between the two braces, paying special attention to +indent it at least by one space.</p> +<pre> + void Form1::newSlot() + { + print STDERR "Hello world from Form1::newSlot(); + if(this->foo()) + { + # do something + } + }</pre> +<p>All Perl code written this way will be saved to the ui.h file, and <strong>puic</strong> will take care of +placing it back in the final program.</p> +<p>Here, after running <strong>puic</strong> on the Form1.ui file, you'd have:</p> +<pre> + sub newSlot + { + print STDERR "Hello world from Form1::newSlot(); + if(this->foo()) + { + # do something + } + }</pre> +<p></p> +<li><strong><a name="item_subclassing_your_gui">Subclassing your GUI</a></strong><br /> +</li> +By using <strong>puic</strong>'s <em>-subimpl</em> option, you may generate a derived module +inheriting your original user interface. +<p>You'd typically generate the derived module once, and write any handcrafted +code in this child. +Then, whenever you need to modify your GUI module, simply regenerate the +parent module, and your child will inherit those changes.</p> +<p>To generate the base module :</p> +<pre> + puic -o Form1.pm form1.ui</pre> +<p>(do this as often as needed, never edit by hand)</p> +<p>To generate the child :</p> +<pre> + puic -o Form2.pm -subimpl Form2 form1.ui</pre> +<p>or</p> +<pre> + puic -o program.pl -x -subimpl Form2 form1.ui</pre> +<p>(do this once and work on the resulting file)</p> +<p></p></ul> +<p> +</p> +<hr /> +<h1><a name="more_development_tools">More development tools</a></h1> +<p>PerlQt comes bundled with two simple programs that can help you to find your way through +the Qt API:</p> +<p> +</p> +<h2><a name="pqtapi">pqtapi</a></h2> +<p>pqtapi is a commandline driven introspection tool.</p> +<pre> + usage: pqtapi [-r <re>] [<class>]</pre> +<pre> + options: + -r <re> : find all functions matching regular expression/keyword <re> + -i : together with -r, performs a case insensitive search + -v : print PerlQt and Qt versions + -h : print this help message</pre> +<p>e.g:</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> is a graphical shell that can be used to test the API interactively. +It is fairly self explanatory and includes an interactive example (<code>Help->Example</code>)</p> +<br/> +<div class='image'><img src="../images/pqtsh.png"/></div><p> +</p> +<hr /> +<h1><a name="known_limitations">Known Limitations</a></h1> +<p>Templated classes aren't available yet (classes derived from templated classes are).</p> +<p> +</p> +<hr /> +<h1><a name="credits">Credits</a></h1> +<p>PerlQt-3 is (c) 2002 Ashley Winters (and (c) 2003 Germain Garand)</p> +<p>Kalyptus and the Smoke generation engine are (c) David Faure and Richard Dale</p> +<p>Puic is (c) TrollTech AS., Phil Thompson and Germain Garand,</p> +<p>The mentioned software is released under the GNU Public Licence v.2 or later.</p> +<p> +</p> +<hr /> +<h1><a name="appendix_1_:_c++_conventions_and_their_perl_counterpart">Appendix 1 : C++ conventions and their Perl counterpart</a></h1> +<p>Whenever you want to use a class/method described in Qt's +<a href="http://doc.trolltech.com">documentation</a> (see also the 'assistant' program bundled with Qt) +from PerlQt, you need to follow some simple translation rules.</p> +<dl> +<dt><strong><a name="item_classnames">Classnames</a></strong><br /> +</dt> +<ul> +<li></li> +All classnames are changed from a <strong>Q</strong> prefix in Qt to a <strong>Qt::</strong> prefix +in Perl. +e.g: QComboBox is named Qt::ComboBox within PerlQt. +<p></p></ul> +<dt><strong><a name="item_functions">Functions</a></strong><br /> +</dt> +<ul> +<li></li> +Functions referenced as <strong>static</strong> are accessed directly, and not through +an object. Thus the static function Foo in class QBar would be accessed from +PerlQt as +<pre> + Qt::Bar::Foo( arg-1,...,arg-n);</pre> +<p>The only notable exceptions are :</p> +<pre> + qApp() will map to Qt::app() + qVersion() will map to Qt::version() # not really needed anymore: we have qVersion(). See Global Functions below.</pre> +<p></p> +<li></li> +Functions referenced as <strong>members</strong> or <strong>Signals</strong> are accessed through an object +with the <strong>-></strong> operator. +e.g: +<pre> + $widget->show;</pre> +<p>There are no fundamental differences between methods and signals, however PerlQt +provides the <strong>emit</strong> keyword as a convenient mnemonic, so that it is clear you +are emitting a 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_by_value">By value</a></strong><br /> +</li> +When an argument isn't preceded by the <strong>&</strong> or <strong>*</strong> character, it is passed by +value. For all basic types such as int, char, float and double, PerlQt will +automatically convert litteral and scalar values to the corresponding C++ type. +<p>Thus for a constructor prototype written as follow in the documentation :</p> +<pre> + QSize ( int w, int h )</pre> +<p>You'd say :</p> +<pre> + Qt::Size(8, 12);</pre> +<p></p> +<li><strong><a name="item_by_reference">By reference</a></strong><br /> +</li> +When an argument is preceded by the <strong>&</strong> character, it means a reference to an +object or to a type is expected. You may either provide a variable name or a +temporary object : +<pre> + $keyseq = Qt::keySequence( &Qt::CTRL + &Qt::F3 ); + $widget->setAccel( $keyseq ); + +or</pre> +<pre> + $widget->setAccel(Qt::keySequence( &Qt::CTRL + &Qt::F3 );</pre> +<p>If the argument isn't qualified as <strong>const</strong> (constant), it means the passed +object may be altered during the process - you must then provide a variable.</p> +<p></p> +<li><strong><a name="item_by_pointer">By pointer</a></strong><br /> +</li> +When an argument is preceded by the <strong>*</strong> character, it means a +pointer to an object or to a type is expected. You may provide a variable +name or the Perl <strong>undef</strong> keyword for a Null pointer. +<p>Similarly, if the argument isn't <strong>const</strong>, the passed object may be altered by +the method call.</p> +<p></p></ul> +<dt><strong><a name="item_enumerations">Enumerations</a></strong><br /> +</dt> +<dd> +Enumerations are sort of named aliases for numeric values that would be hard to +remember otherwise. +</dd> +<dd> +<p>A C++ example would be :</p> +</dd> +<dd> +<pre> + enum Strange { Apple, Orange, Lemon }</pre> +</dd> +<dd> +<p>where <code>Strange</code> is the generic enumeration name, and <code>Apple</code>, <code>Orange</code>, +<code>Lemon</code> its possible values, which are only aliases for numbers (here 0, 1 +and 2).</p> +</dd> +<dd> +<p>Access to enumerations values in Perl Qt is very similar to a static function +call. In fact, it <strong>is</strong> a static function call.</p> +</dd> +<dd> +<p>Therefore, since you probably want to avoid some readability problems, we +recommend the use of the alternate function call syntax : <code>&function</code>.</p> +</dd> +<dd> +<p>Lets now go back to our <code>Strange</code> example.</p> +</dd> +<dd> +<p>If its definition was encountered in the class <code>QFruits</code>, you'd write from +PerlQt :</p> +</dd> +<dd> +<pre> + $apple_plus_orange = &Qt::Fruit::Apple + &Qt::Fruit::Orange;</pre> +</dd> +<p></p> +<dt><strong><a name="item_operators">Operators</a></strong><br /> +</dt> +<dd> +Within PerlQt, <strong>operators overloading</strong> works transparently. +If a given operator is overloaded in a Qt class (which means using it triggers a custom method) +it will behave identically in PerlQt. +Beware though that due to limitations of the Smoke binding library, not all overloaded operators are +available in PerlQt. +You can check the availability of a given operator by using the pqtapi program. +Also, due to outstanding differences between C++'s and Perl's object paradigm, the copy constructor operator (a.k.a '=') +has been disabled. +</dd> +<dd> +<p>e.g-1: '+=' overload</p> +</dd> +<dd> +<pre> + $p1 = Qt::Point(10, 10) + $p2 = Qt::Point(30,40) + $p2 += $p1; # $p2 becomes (40,50) + +e.g-2: '<<' overload</pre> +</dd> +<dd> +<pre> + $f = Qt::File("example"); + $f->open( IO_WriteOnly ); # see 'Constants' below + $s = Qt::TextStream( $f ); + $s << "What can I do with " << 12 << " apples?";</pre> +</dd> +<p></p> +<dt><strong><a name="item_constants">Constants</a></strong><br /> +</dt> +<dd> +Qt doesn't use many constants, but there is at least one place where they are used : for setting +Input/Output flags on files. +In order to avoid the namespace pollution induced by global constants, PerlQt group them in the <strong>Qt::constants</strong> module. +For instance, requesting the importation of all IO constants into the current namespace would be done with: +</dd> +<dd> +<pre> + use Qt::constants;</pre> +</dd> +<dd> +<p>You may also import specific symbols:</p> +</dd> +<dd> +<pre> + use Qt::constants qw( IO_ReadOnly IO_WriteOnly );</pre> +</dd> +<p></p> +<dt><strong><a name="item_global_functions">Global Functions</a></strong><br /> +</dt> +<dd> +Qt has also some utilitarian functions such as bitBlt, qCompress, etc. +</dd> +<dd> +<p>Those were global scope functions and have been grouped in a common namespace: +<code>Qt::GlobalSpace</code>.</p> +</dd> +<dd> +<p>Hence, you shall access this namespace either with a fully qualified call:</p> +</dd> +<dd> +<pre> + Qt::GlobalSpace::qUncompress( $buffer )</pre> +</dd> +<dd> +<p>Or directly, after importation in the current namespace:</p> +</dd> +<dd> +<pre> + use Qt::GlobalSpace; + qUncompress( $buffer )</pre> +</dd> +<dd> +<p>Of course, you may selectively import a few functions:</p> +</dd> +<dd> +<pre> + use Qt::GlobalSpace qw( qUncompress bitBlt )</pre> +</dd> +<dd> +<p><strong>Note:</strong> GlobalSpace has also operators, such has the one performing an addition on two +Qt::Point(). Those operators are called automatically.</p> +</dd> +<dd> +<p>e.g:</p> +</dd> +<dd> +<pre> + $p1 = Qt::Point(10, 10) + Qt::Point(20, 20)</pre> +</dd> +<p></p></dl> +<p> +</p> +<hr /> +<h1><a name="appendix_2_:_internationalization">Appendix 2 : Internationalization</a></h1> +<p>PerlQt handles internationalization by always converting <strong>QString</strong> back to <strong>utf8</strong> in Perl.</p> +<p>Conversions from Perl strings to QStrings are made according to context :</p> +<ul> +<li><strong><a name="item_if_the_perl_string_is_already_utf8%2dencoded">If the Perl string is already utf8-encoded</a></strong><br /> +</li> +then the string will be converted straight to QString. +<p>This is the most convenient and seemless way of internationalizing your application. Typically, one would just enable +the use of utf8 in source code with the <code>use utf8</code> pragma and write its application with an utf8 aware editor.</p> +<p></p> +<li><strong><a name="item_if_the_string_isn%27t_tagged_as_utf8%2c_and_the_us">If the string isn't tagged as utf8, and the <strong>use locale</strong> pragma is not set</a></strong><br /> +</li> +then the string will be converted to QString's utf8 from <strong>ISO-Latin-1</strong>. +<p></p> +<li><strong><a name="item_if_the_string_isn%27t_tagged_as_utf8_and_the_use_l">If the string isn't tagged as utf8 and the <strong>use locale</strong> pragma is set</a></strong><br /> +</li> +then the string will be converted to QString's utf8 according to the currently set <strong>locale</strong>. +<p></p></ul> +<p>Once a string contains utf8, you can convert it back to any locale by setting up <strong>converters</strong> :</p> +<pre> + $tr1=Qt::TextCodec::codecForLocale(); # this one will use current locale + $tr2=Qt::TextCodec::codecForName("KOI8-R"); # that one forces a specific locale (Russian)</pre> +<pre> + print $tr1->fromUnicode(Qt::DateTime::currentDateTime()->toString)."\n\n"; + print $tr2->fromUnicode($my_utf8_string);</pre> +<p>Or, with Perl >= 5.8.0, you may use Perl's <strong>Encode</strong> modules (see <code>perldoc Encode</code>).</p> +<p> +</p> +<h3><a name="disabling_utf8">disabling utf-8</a></h3> +<p>Developers who don't want to use UTF-8 or want to temporarily disable UTF-8 marshalling +for handling legacy programs may use the <strong>use bytes</strong> pragma (and the corresponding <strong>no bytes</strong>).</p> +<p>Within the scope of this pragma, QStrings are marshalled back to ISO-Latin1 (default) or to your locale +(if <strong>use locale</strong> has been set).</p> +<p>Frivole use of this pragma is strongly discouraged as it ruins worldwide standardization efforts.</p> +<p> +</p> +<hr /> +<h1><a name="appendix_3_:_debugging_channels">Appendix 3 : Debugging Channels</a></h1> +<p>The <strong>Qt::debug</strong> module offers various debugging channels/features.</p> +<pre> + use Qt::debug;</pre> +<pre> + use Qt::debug qw|calls autoload verbose|;</pre> +<p>With the simple <code>use Qt::debug</code> statement, the <strong>verbose</strong> and <strong>ambiguous</strong> channels are activated. +If you specify a list of channels within the use statement, then only the specified channels will be enabled.</p> +<p><strong>Available channels :</strong></p> +<ul> +<li><strong><a name="item_ambiguous">ambiguous</a></strong><br /> +</li> +Check if method and function calls are ambiguous, and tell which of the alternatives +was finally elected. +<p></p> +<li><strong><a name="item_verbose">verbose</a></strong><br /> +</li> +Enable more verbose debugging. +<p>Together with <strong>ambiguous</strong>, tell you the nearest matches in case +a method or function call fails. +e.g:</p> +<pre> + use Qt; + use Qt::debug; + $a= Qt::Application(\@ARGV); + $a->libraryPath("foo");</pre> +<pre> + --- No method to call for : + QApplication::libraryPath('foo') + 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> +For every call, tell what corresponding Qt method is called +(detailing the arguments if <strong>verbose</strong> is on). +<p></p> +<li><strong><a name="item_autoload">autoload</a></strong><br /> +</li> +Track the intermediate code between a method invocation in Perl +and its resolution to either a Qt or Perl call. +<p></p> +<li><strong><a name="item_gc">gc</a></strong><br /> +</li> +Give informations about garbage collection +whenever a Qt object is deleted and/or a Perl object is destroyed +<p></p> +<li><strong><a name="item_virtual">virtual</a></strong><br /> +</li> +Report whenever a virtual function tries to access its Perl +reimplementation (wether it exists or not). +<p></p> +<li><strong><a name="item_all">all</a></strong><br /> +</li> +Enable all channels +<p></p></ul> +<p> +</p> +<hr /> +<h1><a name="appendix_4_:_marshallers">Appendix 4 : Marshallers</a></h1> +<p>A marshaller is a piece of ``glue code'' translating a given datatype to another.</p> +<p>Within PerlQt, most Qt objects keep their object nature, so that one may invoke methods on them. +However, some classes and datatypes map so naturally to some Perl types that keeping their object nature would +would feel unnatural and clumsy.</p> +<p>For instance, instead of returning a Qt::StringList object, which would require an iterator to retrieve its content, +PerlQt will translate it to an array reference containing all the object's strings.</p> +<p>In the other way, instead of providing a Qt::StringList object as an argument of a method, one would simply +provide the reference to an array of Perl strings.</p> +<p>Here is the list of Marshallers as of PerlQt-3.008 :</p> +<pre> + ----------------------------------------------------------------- + float, double <=> Perl real (NV) + char, uchar, int, uint, enum + long, ulong, short, ushort <=> Perl integer (IV) + QString, -&, -* => Perl string (utf8) + QString, -&, -* <= Perl string (utf8 or iso-latin1 or locale) + QCString, -&, -* <=> Perl string (utf8 or bytes, according to content or "bytes" pragma) + QByteArray, -&, -* <=> Perl string (bytes) + QStringList, -&, -* => Reference to an array of Perl strings (utf8) + QString, -&, -* => Perl string (utf8 or iso-latin1 or locale) + int&, -* <=> Perl integer (IV) + bool&, -* <=> Perl boolean + char* <=> Perl string (bytes) + char** <= Reference to an array of Perl strings (bytes) + uchar* <= Perl string (bytes) + QRgb* <= Reference to an array of Perl integers (IV) + QCOORD* <= Reference to an array of Perl integers (IV) + void* <=> Reference to a Perl integer (IV) + QValueList<int>, - *, - & <=> Reference to an array of Perl integers (IV) + QCanvasItemList, - *, - & => Reference to an array of Qt::CanvasItem + QWidgetList, - *, - & <=> Reference to an array of Qt::Widget + QObjectList, - *, - & <=> Reference to an array of Qt::Object + QFileInfoList, - *, - & <=> Reference to an array of Qt::FileInfo + QPtrList<QTab>, - *, - & <=> Reference to an array of Qt::Tab + QPtrList<QToolBar>, - *, - & <=> Reference to an array of Qt::ToolBar + QPtrList<QNetworkOperation>, - *, - & <=> Reference to an array of Qt::NetworkOperation + QPtrList<QDockWindow>, - *, - & <=> Reference to an array of Qt::DockWindow + (QUObject*) + +</pre> + +</body> + +</html> diff --git a/doc/fr/Makefile b/doc/fr/Makefile new file mode 100644 index 0000000..1d300c0 --- /dev/null +++ b/doc/fr/Makefile @@ -0,0 +1,7 @@ + +index.html: PerlQt.pod + pod2html --css ../css/pod.css PerlQt.pod > index.html + perl -pi -e 's/cgibin/cgi-bin/' index.html + perl -pi -e 's/#http/http/g' index.html + rm -f pod2*~~ + 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 � <[email protected]> ou le traducteur � +<[email protected]>. 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*) + diff --git a/doc/fr/index.html b/doc/fr/index.html new file mode 100644 index 0000000..2f5e788 --- /dev/null +++ b/doc/fr/index.html @@ -0,0 +1,1120 @@ +<!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�">Un Widget personnalis�</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�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�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�dits">Cr�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�sactiver l'encodage utf8</a></li> + </ul> + + </ul> + + <li><a href="#annexe_3_:_canaux_de_d�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�phane Payrard</strong>, r�vis� et augment� par l'auteur.</p> +<p>Ce document d�crit l'interface Perl au toolkit Qt 3.x. Contacter +l'auteur � <<a href="mailto:[email protected]">[email protected]</a>> ou le traducteur � +<<a href="mailto:[email protected]">[email protected]</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�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�de � �t� �crit en C++ par la soci�t� +Trolltech: <a href="http://www.trolltech.com">Trolltech</a>.</p> +<p>PerlQt3 est fond� sur la librairie +<a href="http://webcvs.kde.org/cgi-bin/cvsweb.cgi/kdebindings/smoke">SMOKE</a>, +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 +<a href="http://webcvs.kde.org/cgi-bin/cvsweb.cgi/kdebindings/kalyptus">kalyptus</a> +de Richard Dale gr�ce au module de David Faure.</p> +<p>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 <a href="http://doc.trolltech.com">manuels en ligne de Qt</a>. Ladite documentation est +la seule r�f�rence qui fasse autorit�.</p> +<p>Si Qt est install� sur votre syst�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�me conforme � 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�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. +<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�sent +document. Se r�f�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�supposent que le r�pertoire courant est +le r�pertoire racine de l'arborescence des sources de PerlQt.</p> +<p>PerlQt utilise le syst�me GNU Autoconf, mais il est pr�f�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-�tre sp�cifier manuellement l'emplacement de Qt � l'aide de l'option :</p> +<pre> + --with-qtdir=/emplacement/de/Qt</pre> +<p>Si la biblioth�que SMOKE est manquante, <code>configure</code> g�n�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�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 <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�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 : +<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�rarchie Perl ordinaire : +<pre> + cd PerlQt + perl Makefile.PL PREFIX=~ + cd ..</pre> +<p>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</p> +<p></p> +<li></li> +Lancez la compilation et l'installation +<pre> + make && make install</pre> +<p>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 :</p> +<pre> + perl -Mlib="~/local/lib/perl/5.x.x" programme.pl</pre> +<p>o� 5.x.x repr�sente la version de Perl utilis�e, ligne qui peut �galement �tre plac�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� sur une +boucle �v�nementielle.</p> +<p>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).</p> +<p>Au lieu de cela, vous cr�ez un objet <strong>Qt::Application</strong> 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.</p> +<p>C'est tout. Qt g�rera les �v�nements et les dirigera vers les +routines appropri�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�e l'objet +application <strong>$a</strong> en lui passant une r�f�rence au tableau <code>@ARGV</code> +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 <strong>Qt::app()</strong>.</p> +<p>La ligne 3, cr�e un PushButton orphelin (c.�.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'�quivalent perlQt d'un +pointeur null en C++.</p> +<p>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: <em>sortir de l'application</em>.</p> +<p>Pour rendre ce widget visible (qui est par d�faut cach�), on +appelle la m�thode <strong>show</strong> [l.6] et lance la boucle +�v�nementielle [l.7].</p> +<p><strong>Sommaire de la syntaxe :</strong></p> +<ol> +<li></li> +Les classes PerlQt sont accessibles par le pr�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�re similaire � C++, un objet est cr�� 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 � 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'�nonce encore plus bri�vement :</p> +<pre> + my $object = Qt::<classname>;</pre> +<p></p> +<li></li> +Comme il a d�j� �t� dit, l'�quivalent Perl d'un pointeur C++ est le mot-cl� +Perl <strong>undef</strong>. +<p>Les pointeurs sont les arguments pr�c�d�s par le caract�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 �tre appel�es de Qt, +parlons du m�canisme d'h�ritage vu de PerlQt.</p> +<p>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 <strong>m�taobjets</strong>.</p> +<p> +</p> +<h3><a name="un_widget_personnalis�">Un Widget personnalis�</a></h3> +<p>R��crivons le programme ``Hello World!'' avec une version personnalis�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�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 � d�finir.</p> +<p>Cr�ons maintenant un constructeur pour notre nouveau widget +en �crivant une routine appel�e <strong>NEW</strong> <em>(notez les majuscules qui +marquent une m�thode diff�rente du constructeur ``new'' usuel)</em>. +Le constructeur PerlQt est appel� <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) � la ligne 9, avec tous les arguments que nous +avons re�us.</p> +<p>Nous cr�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 � partir de notre package +nous pouvons �crire indiff�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�er +ses diff�rents composants � l'int�rieur de variables de scope lexical +(c.�.d d�clar�es par <strong>my</strong>) puisque les widgets sont seulement d�truits +par leur parent et non n�cessairement quand leur conteneur dispara�t +du scope.</p> +<p>En d'autres termes, PerlQt utilise un syst�me de comptage de +r�f�rences pour g�rer la destruction des objets.</p> +<p>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.</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, �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.</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�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� � la ligne 7 et initialis� par un objet <code>Qt::Time</code> +� la ligne 14.</p> +<p>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].</p> +<p><strong>R�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� <strong>NEW</strong> et est appel� 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�rieur d'un package, on acc�de l'instance courante par la +fonction <strong>this</strong>. +<p>Quand une fonction membre est appel�e, les arguments sont accessibles +par le tableau <strong>@_</strong>, mais le premier �l�ment de <strong>@_</strong> n'est pas une +r�f�rence � l'objet contrairement � 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>�crivez plut�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 � +partir d'une classe d�riv�e, utilisez l'attribut sp�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�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 <strong>this</strong>, 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).</p> +<p></p> +<li></li> +Pour r�impl�menter une <strong>fonction virtuelle</strong>, cr�ez simplement une +<strong>sub</strong> de m�me nom que cette fonction. +<p>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'').</p> +<p>Vous pouvez visualiser les noms de m�thodes virtuelles que Qt tentera d'appeler +dans votre classe en pla�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�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.</p> +<p>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 <strong>Signaux et Slots</strong>.</p> +<p>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.</p> +<p>Un composant Qt se comporte comme notre amplificateur ou notre +magn�tophone. Il a des sorties ou <strong>Signaux</strong> et des entr�es ou +<strong>Slots</strong>. 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),</p> +<p>La syntaxe de ce syst�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 � volont� 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�me syntaxe d�crite plus bas).</p> +<p>Chaque slot d�clar� appellera la routine correspondante de votre +objet. Chaque signal d�clar� peut �tre d�clench� via le mot-cl� <strong>emit</strong>.</p> +<p><strong>R��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� �met un signal +<code>clicked()</code> ; nous le connectons donc � notre nouveau slot [ligne 18].</p> +<p>Nous connectons aussi notre signal <code>ChangeLe</code> � notre slot +<code>changement</code>.</p> +<p>Ainsi, quand on appuie (clique) sur notre Button , le signal +<code>clicked()</code> est �mit et d�clenche le slot <code>aEteClicke()</code>. +<code>aEteClicke()</code> �met � 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�rer tr�s profitable pour la clart� 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�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.</p> +<p> +</p> +<hr /> +<h1><a name="d�veloppement_rapide_(rad)_avec_qt_designer_et_puic">D�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�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 <em>sans</em> le plugin sp�cifique. +<p></p></ul> +<p>Aussi puissant et intuitif que soit Qt, �crire une GUI compl�te reste un exercice +fastidieux.</p> +<p>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.</p> +<p>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 <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�cution de la commande :</p> +<pre> + puic -x -o program.pl program.ui</pre> +<p>Cela g�n�rera le package d�fini dans votre fichier ui et un package +principal � fins de test,</p> +<p>Vous pouvez pr�f�rer :</p> +<pre> + puic -o package.pm program.ui</pre> +<p>Cela ne g�n�rera que le package qui pourra �tre utilis� par un programme s�par�.</p> +<p> +</p> +<h2><a name="inclure_des_images">Inclure des Images</a></h2> +<p>Il y a deux mani�res d'inclure des <strong>images ou ic�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�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�� 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 <strong>image</strong>. Vous pouvez +alors g�n�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�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.</p> +<p>Voici une meilleure m�thode :</p> +<ul> +<li><strong><a name="item_�crire_l%27impl�mentation_de_slots_dans_le_designe">�crire l'impl�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�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 <em>Slots/public</em>, +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 <strong><Votre Classe>.ui.h</strong> o� vous pouvez +�crire l'impl�mentation de votre slot. +<p>Par d�faut, il devrait ressembler � 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 �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 �crit sera sauv� dans le fichier ui.h et +<strong>puic</strong> prendra soin de le placer dans notre programme final.</p> +<p>Ici, apr�s l'ex�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�rer un +module d�riv� qui h�rite l'interface utilisateur originelle. +<p>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.</p> +<p>Pour g�n�rer le module de base :</p> +<pre> + puic -o Form1.pm form1.ui</pre> +<p>(fa�tes cela aussi souvent que n�cessaire: n'�ditez jamais +manuellement form1.ui puisqu'il serait �cras�)</p> +<p>Pour g�n�rer le GUI d�riv� :</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�veloppement">Autres outils de d�veloppement</a></h1> +<p>PerlQt comprend �galement deux programmes pouvant vous aider � ma�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 � 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</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�re interactive. +Un exemple dynamique est accessible dans l'entr�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 � mod�le (templates) ne sont pas encore accessibles par PerlQt. +En revanche, les classes d�riv�es de classes � mod�le sont disponibles.</p> +<p>Vous pouvez reconna�tre ce type de classe en ce que leurs arguments comprennent un type g�n�rique plac� entre +les signes ``<'' et ``>''.</p> +<p>ex: + QDictIterator ( const QDict<type> & dict )</p> +<p> +</p> +<hr /> +<h1><a name="cr�dits">Cr�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�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� 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� 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�fixe <strong>Qt::</strong> au lieu de <strong>Q</strong> pour +�tre conforme � l'usage Perl. Ainsi: QComboBox est nomm� 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�d�es directement et non +� travers un objet. Ainsi la fonction statique Foo de la classe <strong>QBar</strong> +peut �tre acc�d�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 � travers l'objet par l'op�rateur + <strong>-></strong> . +Par exemple: +<pre> + $widget->show;</pre> +<p>Il n'y a pas de diff�rence fondamentale entre les m�thodes et les +signaux, n�anmoins PerlQt fournit le mot-cl� <strong>emit</strong> comme une +mn�monique pratique pour rendre clair que vous �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�c�d� par un des caract�res <strong>&</strong> or +<strong>*</strong>, 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++. +<p>Ainsi pour le prototype d'un constructeur �crit dans la documentation +comme ceci: + QSize ( int w, int h )</p> +<p>Vous �crirez :</p> +<pre> + Qt::Size(8, 12);</pre> +<p></p> +<li><strong><a name="item_par_r�f�rence">Par r�f�rence</a></strong><br /> +</li> +Lorsqu'un argument est pr�c�d� par le caract�re <strong>&</strong>, Il est une +r�f�rence � un objet ou � 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� par <strong>const</strong> (constante), l'argument +est un objet qui peut �tre alt�r� 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�c�d� par le caract�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� <strong>undef</strong> � la place +du pointer Null. +<p>De plus, si l'argument est const, l'objet pass� en argument est en +lecture seule: il ne peut pas �tre modifi�.</p> +<p></p></ul> +<dt><strong><a name="item_�num�rations">�num�rations</a></strong><br /> +</dt> +<dd> +Les �numerations sont une forme d'alias pour des valeurs num�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'�num�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�s aux valeurs d'�num�ration en Perl Qt est un appel +de fonction statique.</p> +</dd> +<dd> +<p>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: <code>&fonction</code>.</p> +</dd> +<dd> +<p>Revenons � notre exemple <code>Strange</code>.</p> +</dd> +<dd> +<p>Si nous rencontrons sa d�finition dans la classe <code>QFruits</code>, vous +�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�rateurs">Op�rateurs</a></strong><br /> +</dt> +<dd> +Dans PerlQt, la <strong>surcharge d'op�rateurs</strong> 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. +</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�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 �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.</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�es/Sorties, +o� elles font office de drapeaux pour les modes d'ouverture de fichiers. +</dd> +<dd> +<p>Pour �viter de polluer inutilement l'espace de nom, nous avons regroup� les constantes dans le module +<strong>Qt::constants</strong>, d'o� elles seront charg�es � la demande.</p> +</dd> +<dd> +<p>Ainsi, pour importer l'ensemble des constantes d'E/S, on �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 �t� rassembl�es dans un espace de nom commun: +<code>Qt::GlobalSpace</code>.</p> +</dd> +<dd> +<p>Vous pourrez donc y acc�der soit par un appel pleinement qualifi� :</p> +</dd> +<dd> +<pre> + Qt::GlobalSpace::qUncompress( $buffer )</pre> +</dd> +<dd> +<p>Soit en important pr�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�es :</p> +</dd> +<dd> +<pre> + use Qt::GlobalSpace qw( qUncompress bitBlt )</pre> +</dd> +<dd> +<p><strong>N.B:</strong> 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.</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�mes d'internationalisation en convertissant syst�matiquement les <strong>QString</strong> +de Qt en <strong>utf8</strong> c�t� Perl.</p> +<p>Les conversions en sens inverse, depuis Perl vers Qt sont trait�es diff�remment suivant le contexte :</p> +<ul> +<li><strong><a name="item_si_la_cha�ne_de_caract�re_est_d�j�_marqu�e_comme_�">Si la cha�ne de caract�re est d�j� marqu�e comme �tant utf8</a></strong><br /> +</li> +alors elle sera convertie en QString directement. +<p>C'est la mani�re privil�gi�e d'op�rer, et la plus simple : +Il vous suffit d'ins�rer un pragma <strong>use utf8</strong> 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.</p> +<p></p> +<li><strong><a name="item_si_la_cha�ne_n%27est_pas_marqu�e_comme_utf8%2c_et_">Si la cha�ne n'est pas marqu�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�ne n'est pas marqu�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�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 :</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�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 � ce sujet � la documentation du module <strong>Encode</strong> (<code>perldoc Encode</code>).</p> +<p> +</p> +<h3><a name="d�sactiver_l'encodage_utf8">d�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�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 <strong>use locale</strong> est actif).</p> +<p>Notez bien qu'il est pr�f�rable de <em>ne pas utiliser ce pragma � la l�g�re</em>, 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.</p> +<p> +</p> +<hr /> +<h1><a name="annexe_3_:_canaux_de_d�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�quent d'informations disponibles pour l'adapter � 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�s. +Si vous le faites suivre d'une liste pr�cise de canaux, seuls ceux-ci seront affich�s.</p> +<p><strong>Liste et descriptif des canaux :</strong></p> +<ul> +<li><strong><a name="item_ambiguous">ambiguous</a></strong><br /> +</li> +V�rifier si les appels de m�thodes sont ambigus, et dire quelle m�thode, parmi le jeux +d'alternatives, � finalement �t� choisie. +<p></p> +<li><strong><a name="item_verbose">verbose</a></strong><br /> +</li> +Donner davantage d'informations. +<p>Utilis� avec <strong>ambiguous</strong>, vous donnera les correspondances les plus proches lorsqu'un appel de m�thode �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�e, +en pr�cisant les arguments si <strong>verbose</strong> est actif. +<p></p> +<li><strong><a name="item_autoload">autoload</a></strong><br /> +</li> +D�taille le passage dans le code interm�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 � 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�der � sa r�impl�mentation en Perl +(que cette r�impl�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�es en un autre.</p> +<p>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.</p> +<p>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�.</p> +<p>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.</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�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*)</pre> + +</body> + +</html> diff --git a/doc/images/ex1.png b/doc/images/ex1.png Binary files differnew file mode 100644 index 0000000..140b380 --- /dev/null +++ b/doc/images/ex1.png diff --git a/doc/images/ex2.png b/doc/images/ex2.png Binary files differnew file mode 100644 index 0000000..5e44a51 --- /dev/null +++ b/doc/images/ex2.png diff --git a/doc/images/pqtsh.png b/doc/images/pqtsh.png Binary files differnew file mode 100644 index 0000000..f5929b3 --- /dev/null +++ b/doc/images/pqtsh.png |