FAQ Perl/TkConsultez toutes les FAQ

Nombre d'auteurs : 3, nombre de questions : 86, dernière mise à jour : 24 mai 2013  Ajouter une question

 

Bienvenue sur la FAQ Perl/Tk. Cette FAQ a pour vocation de vous enseigner ou de vous faire revoir les notions de Perl/Tk. N'hésitez pas à utiliser le moteur de recherche.

Vous souhaitez participer à l'amélioration de cette FAQ, n'hésitez pas !! Commentez

Bonne lecture !


SommaireTous les widgetsLes menus (Menu, Menubutton...) (4)
précédent sommaire suivant
 

Pour créer un menu principal (menubar) à sa fenêtre (widget de premier niveau), on utilise la méthode Menu de MainWindows. Le menu sera créé automatiquement en haut de la fenêtre et on ne peut avoir qu'un seul menu par fenêtre. Il sera ensuite possible de créer des sous-menus, de mettre des séparateurs entre ses menus, etc. Voici un code d'exemple :

Code perl : Sélectionner tout
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
#!/usr/bin/perl 
use strict; 
use warnings; 
  
use Tk; 
  
my $main = MainWindow->new( -title => 'Menu', ); 
$main->minsize( 250, 150 ); 
  
#======================== 
# Menu de l'application 
#======================== 
my $menu_bar = $main->Menu( -type => "menubar", ); 
$main->configure( -menu => $menu_bar, ); 
  
# menu fichier avec sous-menu 
my $menu_fichier = $menu_bar->cascade( -label => 'Fichier', -tearoff => 0, ); 
$menu_fichier->command( -label   => 'sous-menu fichier 1', ); 
$menu_fichier->command( -label   => 'sous-menu fichier 2', -image => $main->Getimage("openfile"), -compound => "left"); 
$menu_fichier->command( -label   => 'sous-menu fichier 3', ); 
$menu_fichier->command( -label   => 'sous-menu fichier 4', ); 
my $cascade1 = $menu_fichier->cascade( -label => 'cascade 1', -tearoff => 0, ); 
$cascade1->command( -label   => 'test', ); 
  
$menu_fichier->separator; 
$menu_fichier->command( -label   => 'Quitter', -command => sub { exit;} ); 
  
# menu aide avec sous-menu 
my $menu_aide = $menu_bar->cascade( -label => 'Aide', -tearoff => 0, ); 
$menu_aide->command( -label   => 'sous-menu aide 1', ); 
$menu_aide->command( -label   => 'sous-menu aide 2', ); 
  
# menu TOTO sans sous-menu 
$menu_bar->command( -label   => 'TOTO', ); 
  
$main->Button( -text => 'Quitter', -command => sub {exit;}, )->pack( qw/ -pady 10 / ); 
  
MainLoop;
Voici le résultat obtenu :

Il est aussi possible d'utiliser le widget Menubutton. Mais il est moins adapté dans un contexte de menu principal.

Mis à jour le 25 août 2009 djibril

Si l'on souhaite faire apparaître un menu lorsque l'on clique sur un bouton, il faut utiliser le widget Menubutton. Ce widget permet de créer un menu déroulant qui peut contenir des sous-menus, des boutons radio (avec cases à cocher). Le principe est le suivant : vous cliquez sur le bouton et le menu apparaît. Ce dernier disparaît une fois votre choix effectué ou bien si vous cliquez en dehors du menu. Certains programmeurs utilisent les boutons de menu pour créer un menu principal. Ils les mettent cote à cote dans un cadre (Widget Frame). C'est une technique comme une autre.

Créer un bouton de menu est très simple. Il suffit d'utiliser le widget Menubutton de la sorte :

Code perl : Sélectionner tout
$widget_principal->Menubutton( -text => 'Mon premier bouton de menu',)->pack;
Voici le code complet

Code perl : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/usr/bin/perl 
use warnings; 
use strict; 
use Tk; 
  
# Création du widget principal 
my $widget_principal = new MainWindow( 
  -title      => 'Apprentissage bouton de menu', 
  -background => "white", 
); 
$widget_principal->minsize( 200, 200 ); 
  
my $menu_boutton = $widget_principal->Menubutton( 
  -text      => 'Mon premier bouton de menu', 
  -relief    => 'solid', 
)->pack; 
  
MainLoop;
A ce stade, vous avez un bouton plat qui apparaît. Mais rien n'est fonctionnel. Pour changer l'aspect du bouton, il vous suffit de configurer les options nécessaires.

Le but est d'associer un menu à notre bouton, pour cela, il faut utiliser l'option -menuitems ou -menu. L'option -menuitems permet de créer un menu au moment de la création de bouton de menu. Nous utiliserons cette option dans nos exemples. Si vous optez pour l'option -menu, vous devrez lui associer un menu créé au préalable.

Créons un menu avec plus d'éléments.

Code perl : Sélectionner tout
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
#!/usr/bin/perl 
use warnings; 
use strict; 
use Tk; 
  
# Création du widget principal 
my $widget_principal = new MainWindow( 
  -title      => 'Apprentissage bouton de menu', 
  -background => "white", 
); 
$widget_principal->minsize( 200, 200 ); 
  
my $menu_boutton = $widget_principal->Menubutton( 
  -text      => 'Mon premier bouton de menu', 
  -relief    => 'solid', 
  -menuitems => [ 
    [ 'command', => 'un' ], 
    [ 'command', => 'deux' ], 
    '-',    # séparateur 
    [ 'command', => 'trois' ], 
    [ 'command', => 'quatre' ], 
  ], 
)->pack; 
  
MainLoop;
On obtient ceci :

Actuellement, lorsque l'on clique sur un élément du menu, rien ne se produit. Affichons un texte à chaque clic sur le menu.

Code perl : Sélectionner tout
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
#!/usr/bin/perl 
use warnings; 
use strict; 
use Tk; 
  
# Création du widget principal 
my $widget_principal = new MainWindow( 
  -title      => 'Apprentissage bouton de menu', 
  -background => "white", 
); 
$widget_principal->minsize( 200, 200 ); 
  
my $menu_boutton = $widget_principal->Menubutton( 
  -text      => 'Mon premier bouton de menu', 
  -relief    => 'solid', 
  -menuitems => [ 
    [ 'command', => 'un',   -command => [ \&affichage, 'un' ] ], 
    [ 'command', => 'deux', -command => [ \&affichage, 'deux' ] ], 
    '-',    # séparateur 
    [ 'command', => 'trois',  -command => [ \&affichage, 'trois' ] ], 
    [ 'command', => 'quatre', -command => [ \&affichage, 'quatre' ] ], 
  ], 
)->pack; 
  
MainLoop; 
  
sub affichage { 
  my ($argument) = @_; 
  
  print "=> $argument\n"; 
  return; 
}
A chaque fois que vous cliquerez sur 'un' par exemple, le texte "=> un" sera affiché sur la console. Pour cela, on a utilisé l'option -command que l'on a associée à une procédure nommée 'affichage' dont le but est d'afficher l'argument reçu.

Essayons à présent de rajouter un cinquième élément. De plus, nous allons donner la possibilité à l'utilisateur du script de pouvoir choisir une langue, de choisir une tranche d'âge. Pour ce faire, nous utiliserons la méthode AddItems, créerons des sous-menus et ferons appel à des radiobutton et checkbutton.

Voici le résultat attendu :

Pour ajouter d'autres éléments au menu, nous avons le choix entre deux méthodes : command et AddItems. Les deux méthodes fonctionnent bien.

Code perl : Sélectionner tout
1
2
$menu_boutton->AddItems( [ 'command' => 'cinq', -command => [ \&affichage, 'cinq' ], ] ); 
$menu_boutton->command( -label => 'six', -command => [ \&affichage, 'six' ], );
Pour créer un sous-menu, utilisons la méthode cascade.

Code perl : Sélectionner tout
1
2
3
4
5
6
7
8
my $menu_langue = $menu_boutton->cascade( 
  -label   => 'Vous parlez la langue ?', 
  -tearoff => 0, 
); 
my $menu_age = $menu_boutton->cascade( 
  -label   => "Votre tranche d'âge ?", 
  -tearoff => 0, 
);
Créons maintenant nos différents menus. Voici le code complet.

Code perl : Sélectionner tout
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 
use warnings; 
use strict; 
use Tk; 
  
# Création du widget principal 
my $widget_principal = new MainWindow( 
  -title      => 'Apprentissage bouton de menu', 
  -background => "white", 
); 
$widget_principal->minsize( 200, 200 ); 
  
my $menu_boutton = $widget_principal->Menubutton( 
  -text      => 'Mon premier bouton de menu', 
  -relief    => 'solid', 
  -menuitems => [ 
    [ 'command', => 'un',   -command => [ \&affichage, 'un' ] ], 
    [ 'command', => 'deux', -command => [ \&affichage, 'deux' ] ], 
    '-',    # séparateur 
    [ 'command', => 'trois',  -command => [ \&affichage, 'trois' ] ], 
    [ 'command', => 'quatre', -command => [ \&affichage, 'quatre' ] ], 
  ], 
)->pack; 
  
# rajoutons un élément dans le menu 
$menu_boutton->AddItems( [ 'command' => 'cinq', -command => [ \&affichage, 'cinq' ], ] ); 
$menu_boutton->command( -label => 'six', -command => [ \&affichage, 'six' ], ); 
$menu_boutton->separator; 
  
# Langue 
my $menu_langue = $menu_boutton->cascade( 
  -label   => 'Vous parlez la langue ?', 
  -tearoff => 0, 
); 
my ( $chinois, $anglais, $francais ); 
$menu_langue->checkbutton( 
  -label    => 'chinoise', 
  -variable => \$chinois, 
  -command  => sub { print "Langue chinoise\n"; } 
); 
$menu_langue->checkbutton( 
  -label    => 'anglaise', 
  -variable => \$anglais, 
  -command  => sub { print "Langue anglaise\n"; } 
); 
$menu_langue->checkbutton( 
  -label    => 'française', 
  -variable => \$francais, 
  -command  => sub { print "Langue française\n"; } 
); 
  
# Ma tranche d'âge 
my $menu_age = $menu_boutton->cascade( 
  -label   => "Votre tranche d'âge ?", 
  -tearoff => 0, 
); 
  
my $tranche_age; 
$menu_age->radiobutton( 
  -label    => 'mineur', 
  -value    => 'mineur', 
  -variable => \$tranche_age, 
  -command  => sub { print "Tranche d'âge $tranche_age\n"; } 
); 
$menu_age->radiobutton( 
  -label    => 'majeur', 
  -value    => 'majeur', 
  -variable => \$tranche_age, 
  -command  => sub { print "Tranche d'âge $tranche_age\n"; } 
); 
  
MainLoop; 
  
sub affichage { 
  my ($argument) = @_; 
  
  print "=> $argument\n"; 
  return; 
}
Voilà !!

Mis à jour le 28 septembre 2009 djibril

Il existe une autre méthode pour créer un bouton de menu très simple en utilisant le widget Optionmenu, c'est un menu d'options. Il vous permet de créer un menu déroulant via un clic sur un bouton. Sa mise en place est très simple. Il n'est pas possible de créer des sous-menus.

Voici un exemple :

Code perl : Sélectionner tout
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
#!/usr/bin/perl 
use warnings; 
use strict; 
  
use Tk; 
use utf8; 
  
my $mw = MainWindow->new(); 
  
my ( $var, $tvar ); 
my $option_menu = $mw->Optionmenu( 
  -options => [ 
    [ Janvier => 1 ],   [ Février => 2 ],      
    [ Mars => 3 ],      [ Avril => 4 ], 
    [ Mai => 5],        [ Juin => 6 ], 
    [ Juillet => 7 ],   [ Août =>8 ], 
    [ Septembre => 9 ], [ Octobre => 10 ], 
  ], 
  -command      => sub { print "choix : ", @_, "\n" }, 
  -variable     => \$var, 
  -textvariable => \$tvar 
)->pack; 
  
$option_menu->addOptions( [ 'Novembre' => 11 ], [ 'Décembre' => 12 ], ); 
  
my $cadre = $mw->Frame( -relief => 'groove', -borderwidth => 2 ,-pady => 10)->pack; 
$cadre->Label( -text         => 'Votre choix : ' )->pack( -side => 'left' ); 
$cadre->Label( -textvariable => \$tvar )->pack( -side => 'left',  ); 
$cadre->Label( -textvariable => \$var )->pack( -side => 'left' ); 
  
$mw->Button( -text => 'Fermer', -command => sub { $mw->destroy } )->pack; 
  
MainLoop;
Résultat :

Ce widget ne contient qu'une seule méthode et quatre options. Voir la documentation pour en savoir plus.

Mis à jour le 28 septembre 2009 djibril

Il peut souvent être nécessaire de vouloir créer un menu qui apparaît lorsque l'on clique sur un bouton de la souris. Pour ce faire, on utilise la méthode classique de création de menu, on utilise le widget Menu.

Pour créer le menu, une seule ligne de code suffit

Code perl : Sélectionner tout
$widget->Menu(...Les options...);
Toutes les options sont disponibles dans la documentation du widget Menu. Voici une liste de ces options.

Option Valeur Explication
-activebackground couleur Couleur de fond derrière l'entrée active du menu
-activeborderwidth entier Largeur du contour de l'entrée active
-activeforeground couleur Couleur du texte de l'entrée active
-background couleur Couleur de fond du menu
-borderwidth entier Largeur du contour du menu
-cursor nom Nom du curseur
-disabledforeground couleur Couleur du texte d'une entrée désactivée
-font nom Fonte des textes du menu
-foreground couleur Couleur du texte d'une entrée du menu
-menuitems liste Liste d'entrées du menu créé
-postcommand référence d'une fonction Fonction de rappel invoquée avant que le menu ne s'ouvre
-relief 'flat', 'groove'... Aspect des contours du menu
-selectcolor couleur Couleur de la boîte de sélection des entrées de type case à cocher ou bouton radio
-takefocus 0 ou 1 ou undef Précise si l'on peut parcourir le menu à l'aide du clavier ou non
-tearoff 0 ou 1 Précise si le menu contiendra une ligne de détachement comme première entrée

Ensuite, pour le faire apparaître, on utilisera la méthode post ou Popup.

La méthode post permet d'afficher le menu à un endroit que l'on souhaite en fonction des coordonnées x et y.

Code perl : Sélectionner tout
$menu->post($x, $y);
La méthode Popup permet d'afficher le menu centré sur la fenêtre ou tout autre widget. Mais il est possible de l'ajuster au niveau du pointeur de la souris en utilisant les deux options -popover et -popanchor.

Pour ajouter une entrée au menu, nous pouvons utiliser la méthode add ou insert.

Code perl : Sélectionner tout
1
2
$menu->add(TYPE, OPTIONS); 
$menu->insert(INDICE, TYPE, OPTIONS)
TYPE = 'command', 'radiobutton', 'checkbutton', 'separator' ou 'cascade'.
OPTIONS = les options de menuitems à savoir -activebackground, -activeforeground, -accelerator, -background, -bitmap, -command, -font, -foreground, -image, -indicatoron, -label, -menu, -offvalue, -onvalue, -selectcolor, -selectimage, -state, -underline, -value, -variable...
INDICE = indice avant lequel l'ajout sera effectué. Ex INDICE = 'end', ou '0'.

Voici un exemple pour illustrer toutes les explications ci-dessus.

Code perl : Sélectionner tout
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
#!/usr/bin/perl 
use strict; 
use warnings; 
use Tk; 
use utf8; 
  
my $mw = new MainWindow( 
  -title      => 'Menu', 
  -background => 'white', 
); 
  
# Création d'un menu popup 
my $menu = $mw->Menu( 
  -tearoff    => 0, 
  -takefocus  => 1, 
  -background => "white", 
  -menuitems  => [ 
    [ 'command', => 'un',   -command => [ \&affichage, 'un' ] ], 
    [ 'command', => 'deux', -command => [ \&affichage, 'deux' ] ], 
    '-',    # séparateur 
    [ 'command', => 'trois',  -command => [ \&affichage, 'trois' ] ], 
    [ 'command', => 'quatre', -command => [ \&affichage, 'quatre' ] ], 
  ], 
); 
  
# Ajouter un cinquième élément 
$menu->add( 'command', -label => 'cinq', -command => [ \&affichage, 'cinq' ] ); 
$menu->add('separator'); 
  
# Langue 
my $sous_menu_langue = $menu->cascade( 
  -label   => 'Vous parlez la langue ?', 
  -tearoff => 0, 
); 
my ( $chinois, $anglais, $francais ); 
$sous_menu_langue->checkbutton( 
  -background => 'white', 
  -label    => 'chinoise', 
  -variable => \$chinois, 
  -command  => sub { print "Langue chinoise\n"; } 
); 
$sous_menu_langue->checkbutton( 
  -background => 'white', 
  -label    => 'anglaise', 
  -variable => \$anglais, 
  -command  => sub { print "Langue anglaise\n"; } 
); 
$sous_menu_langue->checkbutton( 
  -background => 'white', 
  -label    => 'française', 
  -variable => \$francais, 
  -command  => sub { print "Langue française\n"; } 
); 
  
# Ma tranche d'âge 
my $menu_cascade_age = $menu->cascade( 
  -label   => "Votre tranche d'âge ?", 
  -tearoff => 0, 
); 
my $tranche_age; 
$menu_cascade_age->radiobutton( 
  -label    => 'mineur', 
  -value    => 'mineur', 
  -background => 'white', 
  -variable => \$tranche_age, 
  -command  => sub { print "Tranche d'âge $tranche_age\n"; } 
); 
$menu_cascade_age->radiobutton( 
  -background => 'white', 
  -label    => 'majeur', 
  -value    => 'majeur', 
  -variable => \$tranche_age, 
  -command  => sub { print "Tranche d'âge $tranche_age\n"; } 
); 
  
  
# afficher un Menu après clic droit sur la souris 
# Le Menu sera affiché au niveau du curseur, il ne sera pas centré,  
# mais affiché au coin supérieur gauche. 
$mw->Tk::bind( '<ButtonPress-3>', sub { $menu->Popup( -popover => 'cursor', -popanchor => 'nw' ); } ); 
  
MainLoop; 
  
sub affichage { 
  my ($argument) = @_; 
  
  print "=> $argument\n"; 
  return; 
}
Voici le résultat :

Il vous suffit de faire un clic avec le bouton droit de la souris pour voir un menu qui apparaît. Le clic droit est géré par la méthode bind. C'est une méthode interne à Tk qui permet de gérer les événements. Consultez la documentation officielle pour en savoir plus.

Mis à jour le 28 septembre 2009 djibril

Proposer une nouvelle réponse sur la FAQ

Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour ça


Réponse à la question

Liens sous la question
précédent sommaire suivant
 

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2019 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.