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

Langage Perl Discussion :

Perl/Tk Rétablir le Focus d'une fenêtre secondaire


Sujet :

Langage Perl

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Février 2006
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Février 2006
    Messages : 22
    Par défaut Perl/Tk Rétablir le Focus d'une fenêtre secondaire
    Bonjour à tous,

    J'ai besoin de votre aide pour résoudre une petit soucis...

    Je tente de développer une application utilisant une fenêtre principale en mode plein écran. À partir de cette fenêtre principale, je veux ouvrir une fenêtre secondaire permettant l'entrée de données spécifique à une tâche. Le code fourni ci-bas (en grande partie trouvé sur le net et en passant merci à tout ceux qui veulent bien partager leur expérience), permet de faire exactement ce que je désire.

    Le seul petit problème, c'est que lorsqu'une fenêtre secondaire (dans ce cas c'est Inscription) est active et que les touches Alt-Tab sont utilisée pour naviguer d'une application à une autre, le focus semble ne pas revenir sur la fenêtre secondaire ce qui empêche de retourner à l'application.

    Votre aide vous experts ;-) serait fort apprécié.

    Voici le code de la fenêtre principale :

    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
     
    #!/usr/bin/perl -w
    # Enduro.pl
    use strict;
     
    use Tk;
    use Inscription;
     
    # Main Window
    my $mw = new MainWindow;
     
    my $w = $mw->screenwidth;
    my $h = $mw->screenheight;
    $mw->overrideredirect (1);
    $mw->MoveToplevelWindow (0,0);
    $mw->geometry (join('x',$w,$h));
     
    # Create a "control window"
    my $control = $mw->Toplevel ( -title => 'Enduro Timing System', );
    $control->geometry ("50x50");
    $control->MoveToplevelWindow(-150,-150);
     
    # Bind FocusIn on the control window
    $control->bind ('<FocusIn>', sub {
        $mw->focusForce;
    });
     
    # Create the Canvas
    my $canvas = $mw->Canvas    (   -width              => 1024,
                                    -height             => 768,
                                    -takefocus          => 0,
                                    -highlightthickness => 0
                                ); 
    $canvas->pack;
     
    # Create all widgets for the Main Window
    my $menu = $mw -> Menubutton (
                            -text => 'Options' ,
                            -tearoff => 0 ,
                            -menuitems => [
                                [ 'command' => 'Inscription' , 
                                    -command => \&Cmd_inscription  ] ,
     
                                [ 'command' => 'Événement' ,
                                    -command => \&Cmd_event ] ,
                                '-' ,
                                [ 'command' => 'Quitter' ,
                                    -command => sub { exit ( 0 ) ; } ]
                            ]
                        ) ;
     
    # Place all the widgets on the screen
    $canvas->createWindow(100, 10, -height => 25, -width => 100, -window => $menu );
     
    # Start the main Loop
    MainLoop();
     
    #------------------------------------------------------------------------------
    # Used to launch the Inscription Window
    #------------------------------------------------------------------------------
    sub Cmd_inscription {
        #&disableFocus();
        my ( $fille , $chaine ) ;
        $fille = $mw -> Inscription ( ) ;
        $chaine = $fille -> Show ( ) ;
        print "$chaine\n" ;
    }
    Enfin le code de la fenêtre secondaire :

    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
     
    #!/usr/bin/perl -w
    # Inscription.pm
     
    use strict;
     
    package Inscription ;
     
    use base qw ( Tk::Toplevel ) ;           # widget composite de type Toplevel
     
    Construct Tk::Widget 'Inscription' ;           
     
    sub Populate
    {
        my ( $this , $args ) = @_ ;
        my ( $bouton , $zone_saisie ) ;
     
        $this -> SUPER::Populate ( $args ) ; # appel de la méthode Populate de la classe mère
     
        $this -> {'texte'} = '' ;
        $this -> {'bouton'} = '' ;
     
        $this -> transient ( $this -> Parent -> toplevel ) ;  # transfuge
        $this -> withdraw ( ) ;                               # retrait de la fenêtre de l'écran
        $this -> protocol ( 'WM_DELETE_WINDOW' => sub { } ) ; # interdit la fermeture 
                                                              # de la fenêtre
     
        $zone_saisie = $this -> Entry ( -textvariable => \$this -> {'texte'} ) ;
        $zone_saisie -> pack ( -padx => 2 , -pady => 2 ) ;
     
        $bouton = $this -> Button ( -text => 'Valider' , 
                                    -command => sub { 
                                                       $this -> {'bouton'} = 'Ok' ; 
                                                }
                          ) ;
     
        $bouton -> pack ( -padx => 2 , -pady => 2 ) ;    
    }
     
    sub Wait
    {
        my ( $this ) = @_ ;
     
        $this -> waitVariable ( \$this->{'bouton'} ) ;   # attend que la valeur de l'attribut   
                                                         # 'bouton' soit modifiée
        $this -> grabRelease ( ) ;                       # relache la capture des événements
        $this -> withdraw ( ) ;                          # retrait de la fenêtre de l'écran
    }
     
    sub Show
    {
        my ( $this ) = @_ ;
     
        my ( $of , $og ) ;
     
        $of = $this -> focusSave ; # mémorisation de la configuration courante du Focus
        $og = $this -> grabSave ;  # mémorisation de la configuration courante de la Capture
     
        $this -> Popup ( ) ;       # afficher la fenêtre
     
        $this -> grab ( ) ;        # capture locale des événements
        $this -> focus ( ) ;       # la fenêtre se voit attribuer le focus
     
        $this -> Wait ( ) ;        # appel à la méthode Wait
     
        $of -> ( ) ;               # restauration de la configuration du Focus
        $og -> ( ) ;               # restauration de la configuration de la Capture
     
        return $this -> {'texte'} ;
    }
     
    1 ;

  2. #2
    Expert confirmé
    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
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $this -> transient ( $this -> Parent -> toplevel ) ;
    Cette ligne n'est-elle pas le problème ? Il me semble bien que ce que tu décris est la définition de transient.

    --
    Jedaï

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Février 2006
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Février 2006
    Messages : 22
    Par défaut
    Je suis un peu dépourvu par manque de connaissances...

    J'ai testé sans cette commande et le résultat est que la fenêtre secondaire crée une nouvelle entrée dans la barre des tâches.

    Tu as raison de dire que cela rêgle en partie le problème mais l'option de pouvoir n'avoir qu'une seule "instance" dans la barre des tâches pour une même application même si plusieurs fenêtre sont ouverte est attraillante...

    Si d'autres options sont disponible ce serait bien...

  4. #4
    Expert confirmé
    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
    Par défaut
    La fait d'avoir une entrée sur la barre des tâches et de pouvoir être atteint par Alt-Tab va de pair à ma connaissance, c'est une limitation de Windows, pas de Tk. Par contre tu peux toujours implémenter un autre raccourci pour passer d'une fenêtre à l'autre à l'intérieur de l'application.

    --
    Jedaï

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Février 2006
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Février 2006
    Messages : 22
    Par défaut
    En fait, cela fonctionne parfaitement lorsque je sépare les deux partie de code que j'ai trouvé sur le net.

    Le problème survient lorsque je tente de combiner les deux. De plus, j'utilise un canvas pour le positionnement de mes widgets ce qui n'est pas le cas des deux exemples.

    Une copie des liens ainsi que le code pour chaque exemple est incluse ci-bas

    http://lionel.romain.free.fr/composite_toplevel.html

    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
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
     
     
    *** Fichier TestSaisie.pl ***
    use Tk ;
    use WidgetSaisie ;
     
    sub Commande
    {
        my ( $fille , $chaine ) ;
        $fille = $fenetre -> WidgetSaisie ( ) ;
        $chaine = $fille -> Show ( ) ;
        print "$chaine\n" ;
    }
     
    # Main
     
    $fenetre = new MainWindow ( ) ;
    $fenetre -> title ( 'TestSaisie' ) ;
     
    $fenetre -> Button ( -text => "Saisir..." , 
                         -command => \&Commande ) -> pack ( -padx => 2 , -pady => 2) ;
     
    MainLoop ( ) ;
     
     
     
    *** Fichier WidgetSaisie ***
     
    package WidgetSaisie ;
     
    use base qw ( Tk::Toplevel ) ;           # widget composite de type Toplevel
     
    Construct Tk::Widget 'WidgetSaisie' ;           
     
    sub Populate
    {
        my ( $this , $args ) = @_ ;
        my ( $bouton , $zone_saisie ) ;
     
        $this -> SUPER::Populate ( $args ) ; # appel de la méthode Populate de la classe mère
     
        $this -> {'texte'} = '' ;
        $this -> {'bouton'} = '' ;
     
        $this -> transient ( $this -> Parent -> toplevel ) ;  # transfuge
        $this -> withdraw ( ) ;                               # retrait de la fenêtre de l'écran
        $this -> protocol ( 'WM_DELETE_WINDOW' => sub { } ) ; # interdit la fermeture 
                                                              # de la fenêtre
     
        $zone_saisie = $this -> Entry ( -textvariable => \$this -> {'texte'} ) ;
        $zone_saisie -> pack ( -padx => 2 , -pady => 2 ) ;
     
        $bouton = $this -> Button ( -text => 'Valider' , 
                                    -command => sub { 
                                                       $this -> {'bouton'} = 'Ok' ; 
                                                }
                          ) ;
     
        $bouton -> pack ( -padx => 2 , -pady => 2 ) ;    
    }
     
    sub Wait
    {
        my ( $this ) = @_ ;
     
        $this -> waitVariable ( \$this->{'bouton'} ) ;   # attend que la valeur de l'attribut   
                                                         # 'bouton' soit modifiée
        $this -> grabRelease ( ) ;                       # relache la capture des événements
        $this -> withdraw ( ) ;                          # retrait de la fenêtre de l'écran
    }
     
    sub Show
    {
        my ( $this ) = @_ ;
     
        my ( $of , $og ) ;
     
        $of = $this -> focusSave ; # mémorisation de la configuration courante du Focus
        $og = $this -> grabSave ;  # mémorisation de la configuration courante de la Capture
     
        $this -> Popup ( ) ;       # afficher la fenêtre
     
        $this -> grab ( ) ;        # capture locale des événements
        $this -> focus ( ) ;       # la fenêtre se voit attribuer le focus
     
        $this -> Wait ( ) ;        # appel à la méthode Wait
     
        $of -> ( ) ;               # restauration de la configuration du Focus
        $og -> ( ) ;               # restauration de la configuration de la Capture
     
        return $this -> {'texte'} ;
    }
     
    1 ;
    http://www.tek-tips.com/faqs.cfm?fid=6265

    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
     
    use Tk;
     
    my $main = MainWindow->new (
        -title => 'My Fullscreen Window',
        -background => 'black',
    );
     
    my $w = $main->screenwidth;
    my $h = $main->screenheight;
    $main->overrideredirect (1);
    $main->MoveToplevelWindow (0,0);
    $main->geometry (join('x',$w,$h));
     
    # Create a "control window"
    my $control = $main->Toplevel (
        -title => 'FS Window',
    );
    $control->geometry ("50x50");
    $control->MoveToplevelWindow(-150,-150);
     
    # Bind FocusIn on the control window
    $control->bind ('<FocusIn>', sub {
        $main->focusForce;
    });

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Février 2006
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Février 2006
    Messages : 22
    Par défaut
    J'ai trouvé une façon de contourner le problème.

    En ajoutant une gestion d'événement qui détecte la sortie de la fenêtre fille, je force le focus à revenir dans cette dernière.

    À la fin du bloc "sub Populate" j'ai ajouté ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $this -> bind ( '<FocusOut>' , sub { $this -> focusForce; } ) ;

    C'est peut être un peu brutal, mais bon ça semble fonctionner.

    Croyez vous que ce truc peut m'apporter des difficultés que je n'ai pas envisagé?

    rp.

Discussions similaires

  1. Perte de focus d'une fenêtre
    Par Taiby dans le forum Débuter
    Réponses: 0
    Dernier message: 10/09/2010, 20h47
  2. [2.0] Perte de focus d'une fenêtre
    Par mister3957 dans le forum Windows Forms
    Réponses: 3
    Dernier message: 29/03/2007, 12h19
  3. Réponses: 8
    Dernier message: 29/08/2006, 10h22
  4. Réponses: 43
    Dernier message: 03/03/2006, 19h41
  5. Comment détecter la perte de focus d'une fenêtre
    Par Leviathan_72 dans le forum Windows
    Réponses: 5
    Dernier message: 31/12/2005, 00h22

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