Salut,
Nouveau tutoriel PERL à propos de la Gestion des sorties standards et d'erreurs en Perl/Tk.
Vos commentaires, corrections et remarques sont les bienvenues.
Merci
Salut,
Nouveau tutoriel PERL à propos de la Gestion des sorties standards et d'erreurs en Perl/Tk.
Vos commentaires, corrections et remarques sont les bienvenues.
Merci
Bonjour,
Si je puis me permettre, j'aurais une solution alternative au III-1 un peu plus élaborée, mais identique dans le principe, car utilisant le tie de Perl.
Cette méthode ne consisterais pas à "associer", à l'aide de tie, directement l'objet Tk au filehandle comme dans III-1, mais à créer une classe permettant de faire la mise à jour de l'objet Tk et d'associer cette classe au filehandle.
La classe en question serait donc une classe héritée de Tie::Handle, et n'aurait que de maigre services à rendre si l'on ne souhaite qu'écrire dans un widget (et pas y lire). Dans ce contexte, il est possible d'écrire la fonction WRITE, PRINT et PRINTF, ce qui permet alors d'utiliser syswrite, print et printf.
Dans le code proposé par Djibril, il suffirait d'ajouter le code suivant avant le code Tk :
et de remplacer :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 package ioTkText; require Tie::Handle; our @ISA = qw(Tie::Handle); # Constructeur sub TIEHANDLE { my $class = shift; # On enregistre la référence de l'objet Tk dans l'instance ioTkText créée my $self = { TkTextWidget => shift }; return bless $self, $class; } # Implémentation de la fonction syswrite sub WRITE { my $self = shift; my ($buf, $len, $offset) = @_; # On peut ignorer la longueur et l'offset, ou bien décider de les utiliser # (ici, ils sont ignorés) $self->{TkTextWidget}->insert("end", $buf); } sub PRINT { my $self = shift; # On appelle WRITE avec la concaténation des éléments de la liste en paramètre $self->WRITE(join "", @_); } sub PRINTF { my $self = shift; # On appelle WRITE avec le formatage défini par les paramètres en faisant appel à sprintf $self->WRITE(sprintf @_); } sub CLOSE { # Indispensable pour fermer correctement le filehandle # Dans notre cas, rien de particulier à faire sur l'objet Tk } package main;
par
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 # Lancement d'une fonctionne qui surveille le STDOUT toutes les 0.5 secondes my $TailleOctetLu = 0; $mw->repeat( 500, [\&LectureFichierParOctets, $FichierSTDOUT, $Scrolled, \$TailleOctetLu] ); MainLoop;
Bien entendu, il est recommandé d'ajouter des contrôles lors de la construction de l'objet ioTkText, notamment pour vérifier que la méthode insert est supportée par l'objet Tk fourni en paramètre.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 tie *STDOUT, qq(ioTkText), $Scrolled; MainLoop;
Merci pour ta contribution.
Mais je n'ai pas bien saisi ton exemple, car ton code est censé être une alternative pour utiliser tie, mais dans l'article, à la section
III-1. Utilisation du module Tk::Text (ou RO::Text),
Je ne parle pas du code
Donc, si je souhaite remplacer ce code
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 # Lancement d'une fonctionne qui surveille le STDOUT toutes les 0.5 secondes my $TailleOctetLu = 0; $mw->repeat( 500, [\&LectureFichierParOctets, $FichierSTDOUT, $Scrolled, \$TailleOctetLu] ); MainLoop;
notamment faire fonctionner
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 #!/usr/bin/perl use warnings; use strict; use POSIX 'acos'; use Tk; my $mw = MainWindow->new; my $text = $mw->Text(qw/-width 40 -height 10/)->pack; tie *STDOUT, ref $text, $text; print "Hello Text World!\n"; printf "pi ~= %1.5f", acos(-1.0); MainLoop;même avec syswrite, est ce que le rajout de ton code suffit ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part tie *STDOUT, ref $text, $text;
As tu un exemple de code ?
Merci
Oups, désolé...
Je voulais dire, en ajouter au code de III-3, le package ioTkText, et en remplaçant dans ce même code ...
Donc l'exemple est celui que tu donnes dans le III-3.
Je l'ai testé, et hormis le bouton "ListerFichiers" qui plante lamentablement (avec ou sans mes modifications), l'affichage est correctement rendu dans la boite Scroller par un simple "print".
L'essentiel est de ne pas associer l'objet Tk directement à STDOUT, mais de passer l'objet Tk en paramètre de l'association (tie) de STDOUT avec la nouvelle classe que je propose dans le code de mon message (ioTkText).
Donc en écrivant :
Code : Sélectionner tout - Visualiser dans une fenêtre à part tie *STDOUT, qq(ioTkText), $Scroller
Bon, en faite, je viens de tester ton code et il fonctionne très bien.
Je peux l'utiliser dès la section
III-1. Utilisation du module Tk::Text (ou RO::Text)
le code est beaucoup plus court et beaucoup plus simple.
De ce faite, je n'ai plus ces soucis :
1. Si nous utilisons syswrite au lieu de print et printf, on aura un message d'erreur "Tk::Error: Can't locate auto/Tk/Text/WRITE.al in @INC ".
2. Seules les fonctions Perl print et printf fonctionnent.
3. Il est impossible de rediriger STDOUT vers un widget Scrolled de type Text.
Car syswrite fonctionne et j'ai testé la redirection vers un scrolled et je n'ai plus de problème .
Ma section III était juste une alternative.
Merci pour ton idée, je n'avais pas penser au module Tie::Handle
Il est donc maintenant beaucoup plus simple (comme la section III.1) pour afficher les print dans un widget. Il suffit juste d'associer au script un .pm contenant le code tie handle.
Bah... j'ai toute une stack de fonction dans Tk qui est déroulée, et un semblant de fenêtre grise qui s'affiche.
Voici la stack :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 Tk::Error: Odd number of args to Tk::Button->new(...) at /usr/lib/perl5/vendor_perl/5.10/i686-cygwin/Tk/Widget.pm line 203 Tk callback for .fbox.frame Tk callback for .fbox.frame1 Tk callback for .fbox.frame2 Tk::Widget::new at /usr/lib/perl5/vendor_perl/5.10/i686-cygwin/Tk/Widget.pm line 164 Tk::Widget::__ANON__ at /usr/lib/perl5/vendor_perl/5.10/i686-cygwin/Tk/Widget.pm line 256 Tk::FBox::Populate at /usr/lib/perl5/vendor_perl/5.10/i686-cygwin/Tk/FBox.pm line 136 Tk::Derived::InitObject at /usr/lib/perl5/vendor_perl/5.10/i686-cygwin/Tk/Derived.pm line 477 Tk::Widget::new at /usr/lib/perl5/vendor_perl/5.10/i686-cygwin/Tk/Widget.pm line 203 Tk::Widget::__ANON__ at /usr/lib/perl5/vendor_perl/5.10/i686-cygwin/Tk/Widget.pm line 256 Tk::DialogWrapper at /usr/lib/perl5/vendor_perl/5.10/i686-cygwin/Tk.pm line 372 Tk::FDialog at /usr/lib/perl5/vendor_perl/5.10/i686-cygwin/Tk.pm line 403 Tk::__ANON__ at /usr/lib/perl5/vendor_perl/5.10/i686-cygwin/Tk.pm line 271 Tk::chooseDirectory at /usr/lib/perl5/vendor_perl/5.10/i686-cygwin/Tk.pm line 352 main::__ANON__ at ./update_text.pl line 82 Tk callback for .button Tk::__ANON__ at /usr/lib/perl5/vendor_perl/5.10/i686-cygwin/Tk.pm line 250 Tk::Button::butUp at /usr/lib/perl5/vendor_perl/5.10/i686-cygwin/Tk/Button.pm line 175 <ButtonRelease-1> (command bound to event)
En effet, c'est bizarre.
Tu as ces message lorsque tu utilises le script de la section III.3 ?
Tu es sous linux je suppute avec Perl 5.10 ? Quelle version de linux ?
as tu installé Tk ou bien est ce Tk par défaut ? Si non installe le et reste.
Sinon pour l'article, je vais créer une section III.4 avec tes rajouts.
- L'idéal serait de compléter le .pm afin de recréer dans WRITE un vrai syswrite
- De tester que le widget passé accepte bien la méthode insert.
- Voir si on ne teste pas autre chose
Non, je ne suis pas sous Linux, mais sous Win32/cygwin, avec un serveur X CygwinX lancé.
Je n'ai pas installé Tk, qui l'était déjà lors de l'installation standard de perl sous cygwin.
La version de perl est 5.10.0
Pour tester la présence de la méthode insert dans le constructeur, j'aurais tendance à écrire la chose suivante :
Cependant, la méthode can retourne faux pour l'objet Tk::Scrolled (qui se trouve être identifié comme un objet Tk::Frame).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 sub TIEHANDLE { my $class = shift; my $self = { TkTextWidget => $_[0] }; $_[0]->can(qq(insert)) or die "L'object ".ref($_[0])." ne supporte pas la méthode 'insert'"; return bless $self, $class; }
Etrange quand on sait que l'appel à la méthode insert de l'objet Scrolled fonctionne... sans doute un problème d'écriture de cette classe au niveau de l'héritage, ou une erreur dans mon test
Il existe des méthodes Tk permettant de tester les widgets. Je pense qu'il est plus propre de s'en référer.
Je coltine un petit code.
Ah ! super. En fait, j'y connais pas grand chose en Tk
Sinon, je te conseil grandement d'installer activeperl (version 5.8 ou 5.10) au lieu de bosser sous Perl cygwin. Tu auras beaucoup beaucoup moins de soucis avec certains modules.
En fait, j'utilise cygwin pour bien d'autres choses que perl, c'est la raison pour laquelle j'utilise principalement perl sous cet environnement.
Par ailleurs, je n'ai jamais rencontré de problème particulier avec l'usage de cygwin et perl (sachant que jusqu'à présent, je n'utilise pas d'interface graphique).
Je vais essayer de ré-installer Tk qui n'est peut-être pas à jour.
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager