GtkFr - Cours Gtk+-2

PyLesBoutonsPartieDeux

PageAccueil :: LesNews :: Telechargement :: Liens :: Forum :: LeChat :: Contact
DerniersChangements :: DerniersCommentaires :: ParametresUtilisateur :: Vous êtes 38.107.191.92
<< Les boîtes de dialogue PyGtk Les menus >>


Les boutons (Partie 2)

1. Présentation

Nous allons étudier cette fois-ci trois nouveaux types de boutons qui dérivent du widget GtkButton. L'étude de ces widgets sera rapide car ils ne comportent que très peu de fonctions.

1.1 Hiérarchie

GObject -> GtkObject -> GtkWidget -> GtkContainer -> GtkBin? -> GtkButton -> GtkToggleButton
GObject -> GtkObject -> GtkWidget -> GtkContainer -> GtkBin? -> GtkButton -> GtkToggleButton -> GtkCheckButton
GObject -> GtkObject -> GtkWidget -> GtkContainer -> GtkBin? -> GtkButton -> GtkToggleButton -> GtkCheckButton -> GtkRadioButton

2. Le bouton poussoir

Le widget GtkToggleButton est un bouton poussoir qui ne peut prendre que deux états : enfoncé ou relâché.

2.1 Création

Comme d'habitude, il n'y a rien de bien compliqué vu que c'est toujours le même principe :
toggle_button = gtk.ToggleButton?(label=None, use_underline=True)
Sans paramètre, vous obtenez un nouveau bouton vide, si vous donner un paramètre label, vous ajoutez du texte à l'intérieur et si vous utilisez un texte avec un _, vous ajouter en plus un raccourci clavier.

2.2 Etat du bouton

Il peut être intéressant de connaître l'état du bouton pour agir en conséquence. Une fois encore, rien de plus simple on utilise la fonction :
actif = toggle_button.get_active()
Cette dernière nous renvoie True si le bouton est enfoncé et False sinon.
Pour modifier l'état du bouton, c'est aussi simple :
toggle_button.set_active(is_active)
Il suffit de mettre le paramètre is_active à True si l'on veut enfoncer le bouton ou à False pour le relâcher.

2.3 Apparence du bouton

Il existe cependant un troisième état qui n'est pas accessible en cliquant sur le bouton mais par une fonction spécifique. Ce troisième état, vous le connaissez sûrement. Le meilleur exemple est celui des éditeurs de texte :
Vous avez une phrase dans laquelle il y a du texte normal et du texte en gras. Si vous sélectionnez le texte en gras, le bouton permettant justement de le mettre en gras s'enfonce (en général B). Par contre si vous sélectionnez le texte normal, ce même bouton repasse à son état relâché. Venons en au troisième état, qui apparaît lorsque vous sélectionnez la phrase entière. Le bouton ne change pas d'état mais seulement d'aspect, il donne l'impression d'être inactif.
Ce changement d'aspect doit se faire manuellement, et s'effectue avec cette méthode :
toggle_button.set_inconsistent(setting)
Il suffit de mettre le paramètre setting à True pour donner au bouton l'aspect inactif.
Et pour connaître l'aspect du bouton, il y a tout naturellement la fonction :
etat = toggle_button.get_inconsistent()

2.4 Programme exemple

Nous allons construire une application contenant un GtkToggleButton qui changera d'état (bien sûr) lorsque nous cliquerons dessus, mais aussi lorsque nous cliquerons sur un deuxième bouton (le changement d'état entraînera la modification du label). De plus, il y aura un troisième bouton pour changer l'aspect du bouton (idem, on change aussi le label).
# -*- Encoding: Latin-1 -*-
import gtk

def main():
    window = gtk.Window(gtk.WINDOW_TOPLEVEL)
    window.set_title("GtkToggleButton")
    window.set_default_size(320, 200)

    vbox = gtk.VBox(True, 0)
    window.add(vbox)

    # Creation du label du bouton
    label = u"Etat : Relâché - Aspect : Normal"
    # Creation du bouton GtkToggleButton
    toggle_btn = gtk.ToggleButton(label)
    # Le label sLabel n'est plus utile

    vbox.pack_start(toggle_btn, False, False, 0)

    etat_btn = gtk.Button("CHANGER ETAT")
    vbox.pack_start(etat_btn, False, False, 0)

    aspect_btn = gtk.Button("CHANGER ASPECT")
    vbox.pack_start(aspect_btn, False, False, 0)

    window.show_all()

    # Connexion des signaux
    window.connect("destroy", gtk.main_quit, None)
    toggle_btn.connect("toggled", OnToggle, None)
    etat_btn.connect("clicked", OnEtatBtn, toggle_btn)
    aspect_btn.connect("clicked", OnAspectBtn, toggle_btn)

    gtk.main()

def OnEtatBtn(widget, toggle):
    # Recuperation de l etat du bouton
    etat = toggle.get_active()

    # Modification de l etat du bouton
    toggle.set_active(etat ^ True)

def OnAspectBtn(etat_btn, toggle):
    # Recuperation de l aspect du bouton
    inconsistent = toggle.get_inconsistent()

    # Modification de l'aspect du bouton
    toggle.set_inconsistent(inconsistent ^ True)

    # On emet le signal "toggle" pour changer le texte du bouton
    toggle.toggled()

def OnToggle(toggle, data):
    # Recuperation de l etat du bouton
    etat = toggle.get_active()
    # Recuperation de l aspect du bouton
    inconsistent = toggle.get_inconsistent()

    # Construction du label du bouton
    Etat = {True:u'Enfoncé', False:u'Relâché'}
    Inconsistent = {True: u'Modifié', False: u'Normal'}
    label = "Etat : %s - Aspect : %s" % (Etat[etat], Inconsistent[inconsistent])

    # Modification du label du bouton
    toggle.set_label(label)
Résultat :






3. Les cases à cocher

3.1 Création

Une fois encore, la syntaxe et l'utilisation des fonctions de création restent classiques :
widget = gtk.CheckButton?(label=None, use_underline=True)
Il n'existe pas d'autres fonctions pour ce widget, il faut donc utiliser les fonctions des widgets GtkToggleButton et GtkButton pour récupérer les propriétés du widget (état, aspect, label, ...).

3.2 Programme exemple

Nous n'allons pas ici créer de programme exemple pour ce widget car il suffit juste de remplacer gtk_toggle_button_new_with_label par gtk_check_button_new_with_label dans l'exemple précédent pour obtenir ceci :







4. Les boutons GtkRadioButton

Nous allons maintenant le widget GtkRadioButton qui se différencie des autres boutons par la possibilité d'en grouper plusieurs. De ce fait, lorsque par exemple nous avons un groupe de trois boutons, il n'y en a qu'un seul qui pourra être actif. On pourrait très bien faire cela avec le widget GtkCheckButton mais cela serait beaucoup plus long à programmer.

4.1 Création

Afin de grouper les boutons radio, GTK+ utilise les listes simplement chaînées de GLib. Pour créer le premier bouton radio du groupe, il faut obligatoirement passer par une de ces fonctions :
widget = gtk.RadioButton?(group=None, label=None, use_underline=True)
Au moment de la création, le bouton radio est automatiquement ajouté à la liste group. Cependant, ce paramètre n'est pas obligatoire. Nous pouvons très bien mettre None comme valeur et cela marchera de la même manière, sauf que nous n'aurons pas de pointeur sur la liste. La valeur de retour de cette fonction sera aussi copiée dans la variable data de la liste chaînée.
Ensuite pour rajouter les autres boutons au groupe, il y a plusieurs possibilités. La première est d'utiliser une des trois fonctions précédentes mais ce n'est pas tout, car autant pour le premier bouton du groupe, il n'est pas nécessaire d'avoir une liste, autant pour les autres boutons cela devient obligatoire. Pour cela, GTK+ nous fournit une fonction qui permet d'obtenir la liste dans laquelle les boutons du groupe sont ajoutés :
liste = radio_button.get_group()
Avec cette fonction, nous pouvons donc connaître la liste à laquelle appartient le bouton radio_button, ce qui va nous permettre d'ajouter de nouveau bouton au groupe. Mais là où cela se complique, c'est qu'il faut récupérer la liste avant chaque ajout de bouton avec le dernier bouton ajouté comme paramètre. Voici ce que cela donnerai pour un groupe de trois boutons :
radio1 = gtk.RadioButton?(label="Radio 1")
Group = radio1.get_group()
radio2 = gtk.RadioButton?(Group, label="Radio 2")
Group = radio2.get_group()
radio3 = gtk.RadioButton?(Group, "Radio 3")
Ce système peut donc s'avérer lourd lors de la création du groupe, surtout s'il contient un grand nombre de boutons. Heureusement, on peut utiliser un widget RadioButton? comme paramètre group.
Cette fois group ne correspond pas à la liste mais à un des boutons du groupe. A chaque appel d'une de ces fonctions GTK+ va s'occuper de récupérer correctement la liste à laquelle appartient le bouton group et ajouter le nouveau bouton. Cela aura pour conséquence, dans le cas d'un groupe de trois boutons, de réduire le nombre de lignes de code de 5 à 3 (et oui, une ligne de code c'est une ligne de code).
Nous savons maintenant tout ce qu'il faut pour créer un groupe de GtkRadioButton.

4.2 Programme exemple

Le programme exemple se présente sous la forme d'un mini sondage à trois choix :
La possibilité de choisir parmi une de ces valeurs est rendue possible par l'utilisation des GtkRadioButton. Un autre bouton (tout ce qu'il y a de plus normal) permet de valider le choix fait par l'utilisateur ainsi que d'afficher le résultat dans une boîte de dialogue.
# -*- Encoding: Latin-1 -*-
import gtk

def main():
    window = gtk.Window(gtk.WINDOW_TOPLEVEL)
    window.set_title("GtkRadioButton")
    window.set_default_size(320, 200)

    vbox = gtk.VBox(True, 0)
    window.add(vbox)

    label = gtk.Label("Votre choix :")
    vbox.pack_start(label, False, False, 0)

    # Creation du premier bouton radio
    radio1 = gtk.RadioButton(label="Pour")
    vbox.pack_start(radio1, False, False, 0)
    # Ajout du deuxieme
    radio2 = gtk.RadioButton(radio1, "Contre")
    vbox.pack_start(radio2, False, False, 0)
    # Ajout du troisieme
    radio3 = gtk.RadioButton(radio1, "Sans opinion")
    vbox.pack_start(radio3, False, False, 0)

    valider = gtk.Button(stock=gtk.STOCK_OK)
    vbox.pack_start(valider, False, False, 0)

    window.show_all()

    # Connexion des signaux
    window.connect("destroy", gtk.main_quit, None)
    valider.connect("clicked", OnValider, radio1)

    gtk.main()

def OnValider(btn, data):
    # Recuperation de la liste des boutons
    liste = data.get_group()

    # Parcours de la liste
    for bouton in liste:
        # Le bouton est il selectionne
        if bouton.get_active():
            # OUI -> on copie le label du bouton
            label = bouton.get_label()
            # On sort de la boucle
            break

    # On recupere la fenetre principale
    #
    # A partir d'un widget, gtk_widget_get_toplevel
    # remonte jusqu'a la fenetre mere qui nous est
    # utile pour l'affichage de la boite de dialogue
    window = bouton.get_toplevel()

    info = gtk.MessageDialog(window,
        gtk.DIALOG_MODAL,
        gtk.MESSAGE_INFO,
        gtk.BUTTONS_OK,
        "Vous avez choisi : %s" % label)

    info.run()

    info.destroy()

if __name__ == '__main__':
    main()
Résultat :





<< Les boîtes de dialogue PyGtk Les menus >>

Il n'y a pas de commentaire sur cette page. [Afficher commentaires/formulaire]
Apinc