IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Interfaces Graphiques Perl Discussion :

Tk, repeat mais 1 seule fois


Sujet :

Interfaces Graphiques Perl

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7
    Points : 6
    Points
    6
    Par défaut Tk, repeat mais 1 seule fois
    Bonjour à tous,
    dans mon programme perl j'utilise une interface Tk. Il y a une fenêtre principale contenant 3 objets "Text". Je mets à jour le contenu de ces fichiers grâce à la méthode "repeat". Un extrait de mon code:

    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
     
    	my $top = MainWindow()->Toplevel(-title => 'log');
    	my $OIText = $top->Scrolled('Text', -scrollbars => 'se', -wrap => 'none', -width => 120, -height => 20);
    	my $DataText = $top->Scrolled('Text', -scrollbars => 'se', -wrap => 'none', -width => 120, -height => 20);
    	my $IOText = $top->Scrolled('Text', -scrollbars => 'se', -wrap => 'none', -width => 120, -height => 20);
     
    	$OIText->pack(-fill => 'both');
    	$DataText->pack(-fill => 'both');
    	$IOText->pack(-fill => 'both');
    	open(my $OIFH, "OIBufferFile");
    	$OIText->repeat(50, sub {
    		my @lines = <$OIFH>;
    		if (scalar(@lines) > 0) {
    			$OIText->insert('end', @lines);
    			$OIText->see('end');
    		}
    	});
     
    	open(my $DataFH, "DataBufferFile");
    	$DataText->repeat(10, sub {
    		my @lines = <$DataFH>;
    		if (scalar(@lines) > 0) {
    			$DataText->insert('end', @lines);
    			$DataText->see('end');
    		}
    	});
     
    	open(my $IOFH, "IOBufferFile");
    	$IOText->repeat(100, sub {
    		my @lines = <$IOFH>;
    		if (scalar(@lines)) {
    			$IOText->insert('end', @lines);
    			$IOText->see('end');
    		}
    	});
    Je souhaiterais réaliser des opérations plus complexes mais surtout qu'une seule fois. Par exemple si je reprends la première partie de mon code;

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    	$OIText->METHODE_EXECUTEE_UNE_FOIS( sub {
    		open(my $OIFH, "OIBufferFile");
    		while(my $line = <$OIFH>) {
    			# je fais plein de trucs super compliqués:
    			# code volumineux
    			$OIText->insert('end', $line);
    			$OIText->see('end');
    		}
    		close($OIFH);
    	});
    	# TRES IMPORTANT l'interprétation du code se poursuit
    Après maintes recherches, je n'ai toujours pas trouvé la
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    METHODE_EXECUTEE_UNE_FOIS
    qui comme vous l'aurez remarqué se comporte comme un .

    Merci d'avance pour votre aide,

    JD
    Plus je pédale moins vite et moins j'avance plus vite.

  2. #2
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    427
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 427
    Points : 459
    Points
    459
    Recherche staigiaire(s) motivé(s) sur projet perl/reseau a grande echelle. Me contacter par mp.

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7
    Points : 6
    Points
    6
    Par défaut after but I have to wait!
    Le problème de la méthode after et qu'il faut attendre la fin de l'exécution du callback pour passer à la suite de l'interprétation du code. Or ce que je souhaiterais justement, c'est que la méthode n'attende pas la fin du callback pour passer à la suite du code. Pour expliciter mes propos voici un code que vous pouvez tester:

    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
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    #!/usr/bin/perl -w
     
    use strict;
     
    use Tk;
    use Tk::Table;
     
    # choix de l'utilisateur
    print "pour AFTER tapez 0, pour REPEAT tapez 1: ";
    my $stdin = <STDIN>;
    chomp($stdin);
     
     
    my $mw = MainWindow->new();
    # largeur et hauteur du caneva
    my ($width, $height) = (600, 400);
     
    my $table = $mw->Table(-scrollbars => 'e');
    my $canvas = $mw->Canvas(-width => $width, -height => $height);
    my $scale =  $mw->Scale(-from => 0, -resolution => 1, -orient => 'horizontal');
    # quand le "scale" est modifie alors la region visible est deplacee
    # scrollregion: $x, $y, $w, $h
    $scale->configure(-command => sub {$canvas->configure(-scrollregion => [$scale->get() - $width,0, $scale->get(), $height]);});
     
    $table->pack(-fill=>'both');
    $table->put(0,0,$table->Label(-text => "Canvas"));
    $table->put(0,1,$canvas);
     
    $scale->pack(-fill=>'both');
     
    # coordonnees des 4 cercles
    # [extremite_droite, extremite_basse, extremite_gauche, extremite_haute]
    my @ovals = ([100,100,0,0],[250,200,150,100],[1000,300,900,200],[1600,300,1500,200]);
     
    # maximum des abscisses
    my $max = 0;
     
     
    if ($stdin eq '0') {
    	$mw->after(0, sub {
    		foreach my $oval (@ovals) {
    			# creation du cercle
    			$canvas->create('oval', @{$oval}, -fill => 'red');
    			# si l'extremite droite du cercle est superieure au max alors
    			if ($oval->[0] > $max) {
    				# on initialise la variable max
    				$max = $oval->[0];
    				# la borne droite du "scale" est mise au max
    				$scale->configure(-to => $max);
    				# le curseur du "scale" est mis au max et consequemment la commande est activee
    				# -command deplace la region visible au max droit (puisque c'est une serie temporelle)
    				$scale->set($max);
    			}
    			print "on attend...\n";
    			sleep(1);
    		}
    	});
    } elsif ($stdin eq '1') {
    	my $i = 0;
    	$mw->repeat(1000, sub {
    		if ($i <= $#ovals) {
    			# creation du cercle
    			$canvas->create('oval', @{$ovals[$i]}, -fill => 'red');
    			# si l'extremite droite du cercle est superieure au max alors
    			if ($ovals[$i]->[0] > $max) {
    				# on initialise la variable max
    				$max = $ovals[$i]->[0];
    				# la borne droite du "scale" est mise au max
    				$scale->configure(-to => $max);
    				# le curseur du "scale" est mis au max et consequemment la commande est activee
    				# -command deplace la region visible au max droit (puisque c'est une serie temporelle)
    				$scale->set($max);
    			}
    			$i++;
    		}
    	});
    }
     
    $mw->MainLoop();
    Plus je pédale moins vite et moins j'avance plus vite.

  4. #4
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    C'est impossible sans utiliser de threads, ou de processus supplémentaires. Ou éventuellement en rajoutant des DoOneEvent() un peu partout dans ta sous-routine (pourvu qu'il n'y ait pas une seule grosse opération blocante).

    --
    Jedaï

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7
    Points : 6
    Points
    6
    Par défaut
    Merci pour les conseils, visiblement il n'y a pas de solution simple alors...
    Plus je pédale moins vite et moins j'avance plus vite.

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    427
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 427
    Points : 459
    Points
    459
    Par défaut
    de deux choses l'une: soit tu maitrise toi meme le truc bloquant (genre boucle for ou autre) et tu peu glisser der dooneevent ou update comme te le conseil jedai, soit c'est une grosse fonction externe sur laquelle tu n'a pas la main (genre ton telnet) et la tu dois utiliser un thread ou un fork (avec dans les deux cas des difficultés pour savoir quand l'operation est terminée et recuperer un eventuel resultat).
    Mais tu a encore une autre possibilité, pas simple nonplus: si ton operation bloquante est une operation reseau alors tu peu utiliser l'un des nombreux framework reseau asynchrone qu'on trouve sur cpan. Par exemple POE integre surement une libe telenet (à verifier), et tu peux le faire interagir sans prob avec TK.
    Tout se passera alors dans ton process, mais sans bloquage: POE se chargera de decouper lui meme la grosse operation telnet bloquante en multiples appels non bloquants, et tout sera transparent pour toi: tu donnera une callaback qui sera rappellée une fois l'operation terminée.
    Recherche staigiaire(s) motivé(s) sur projet perl/reseau a grande echelle. Me contacter par mp.

Discussions similaires

  1. Réponses: 6
    Dernier message: 20/09/2011, 15h39
  2. lu tous les jours mais exécuté une seule fois par mois
    Par sianto dans le forum Scripts/Batch
    Réponses: 13
    Dernier message: 17/11/2008, 09h08
  3. Réponses: 18
    Dernier message: 10/02/2005, 13h22
  4. Réponses: 2
    Dernier message: 30/11/2004, 11h48
  5. lancer 1 seul fois l'exe..
    Par lamalice dans le forum Windows
    Réponses: 8
    Dernier message: 27/10/2004, 15h26

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo