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

Apprendre à utiliser le module Python PyGTK 2.0


précédentsommairesuivant

VI. Chapitre 6. Les boutons

VI-A. Les boutons simples

Nous avons pratiquement déjà fait le tour du widget bouton. Il est en effet très simple. Lors de la création d'un bouton avec la fonction gtk.Button(), vous pouvez lui donner une étiquette en lui passant une chaine de caractères. Mais vous pouvez tout aussi bien créer un bouton vierge en ne passant rien à la fonction ; il vous suffira ensuite, si vous le souhaitez, de placer une étiquette ou une image "pixmap" dans ce nouveau bouton. Pour ce faire, créez une nouvelle boite et placez-y vos objets avec l'habituelle pack_start(). Puis, avec add(), placez la boite dans le bouton.

La fonction de création des boutons est la suivante :

 
Sélectionnez
  bouton = gtk.Button(label=None, stock=None)

Si l'on donne une chaine de caractères à l'argument label, elle sera affichée sur le bouton. L'argument stock, quant à lui, sert à afficher sur le bouton une icône du stock de GTK ainsi que le texte correspondant. Les éléments du stock sont :

 
Sélectionnez
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.
  STOCK_DIALOG_INFO
  STOCK_DIALOG_WARNING
  STOCK_DIALOG_ERROR
  STOCK_DIALOG_QUESTION
  STOCK_DND
  STOCK_DND_MULTIPLE
  STOCK_ADD
  STOCK_APPLY
  STOCK_BOLD
  STOCK_CANCEL
  STOCK_CDROM
  STOCK_CLEAR
  STOCK_CLOSE
  STOCK_CONVERT
  STOCK_COPY
  STOCK_CUT
  STOCK_DELETE
  STOCK_EXECUTE
  STOCK_FIND
  STOCK_FIND_AND_REPLACE
  STOCK_FLOPPY
  STOCK_GOTO_BOTTOM
  STOCK_GOTO_FIRST
  STOCK_GOTO_LAST
  STOCK_GOTO_TOP
  STOCK_GO_BACK
  STOCK_GO_DOWN
  STOCK_GO_FORWARD
  STOCK_GO_UP
  STOCK_HELP
  STOCK_HOME
  STOCK_INDEX
  STOCK_ITALIC
  STOCK_JUMP_TO
  STOCK_JUSTIFY_CENTER
  STOCK_JUSTIFY_FILL
  STOCK_JUSTIFY_LEFT
  STOCK_JUSTIFY_RIGHT
  STOCK_MISSING_IMAGE
  STOCK_NEW
  STOCK_NO
  STOCK_OK
  STOCK_OPEN
  STOCK_PASTE
  STOCK_PREFERENCES
  STOCK_PRINT
  STOCK_PRINT_PREVIEW
  STOCK_PROPERTIES
  STOCK_QUIT
  STOCK_REDO
  STOCK_REFRESH
  STOCK_REMOVE
  STOCK_REVERT_TO_SAVED
  STOCK_SAVE
  STOCK_SAVE_AS
  STOCK_SELECT_COLOR
  STOCK_SELECT_FONT
  STOCK_SORT_ASCENDING
  STOCK_SORT_DESCENDING
  STOCK_SPELL_CHECK
  STOCK_STOP
  STOCK_STRIKETHROUGH
  STOCK_UNDELETE
  STOCK_UNDERLINE
  STOCK_UNDO
  STOCK_YES
  STOCK_ZOOM_100
  STOCK_ZOOM_FIT
  STOCK_ZOOM_IN
  STOCK_ZOOM_OUT

Le programme boutons.py donne un exemple d'utilisation de gtk.Button() pour créer un bouton contenant une image et une étiquette. Le code de création de la boite est séparé du reste afin que vous puissiez l'utiliser dans vos programmes. Nous verrons d'autres exemples faisant appel à des images un peu plus loin dans ce tutoriel. La figure 6.1 montre la fenêtre et son bouton qui contient une étiquette et une image "pixmap" :

Image non disponible
Figure 6.1. Bouton avec étiquette et image pixmap

Voici le code source du programme boutons.py :

 
Sélectionnez
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.
#!/usr/bin/env python

# exemple boutons.py

import pygtk
pygtk.require('2.0')
import gtk

# On crée une boite verticale, on y place une image 
# et une étiquette, et on renvoie la boite.

def boite_xpm_etiquette(parent, fichier_xpm, texte_etiquette):
    # On crée une boite pour la pixmap et l'étiquette
    boite1 = gtk.HBox(False, 0)
    boite1.set_border_width(2)

    # A présent l'image.
    image = gtk.Image()
    image.set_from_file(fichier_xpm)

    # On crée une étiquette pour le bouton.
    etiquette = gtk.Label(texte_etiquette)

    # On place la pixmap et l'étiquette dans la boite.
    boite1.pack_start(image, False, False, 3)
    boite1.pack_start(etiquette, False, False, 3)

    image.show()
    etiquette.show()
    return boite1

class Bouton:
    # Notre méthode de rappel habituelle.
    def salut(self, widget, donnees=None):
        print "Salut ! - Clic sur le %s." % donnees

    def __init__(self):
        # Création d'une nouvelle fenêtre.
        self.fenetre = gtk.Window(gtk.WINDOW_TOPLEVEL)

        self.fenetre.set_title("Bouton et image")

        # C'est une bonne idée de faire ceci pour chaque fenêtre.
        self.fenetre.connect("destroy", lambda wid: gtk.main_quit())
        self.fenetre.connect("delete_event", lambda a1,a2: gtk.main_quit())

        # On fixe la largeur des bordures de la fenêtre.
        self.fenetre.set_border_width(10)

        # Création d'un nouveau bouton.
        bouton = gtk.Button()

        # On connecte le signal "clicked" du bouton à la fonction de rappel
        bouton.connect("clicked", self.salut, "bouton cool")

        # Ceci appelle notre fonction de création de boites.
        boite1= boite_xpm_etiquette(self.fenetre, "info.xpm", "bouton cool")

        # On place et on affiche tous nos widgets.
        bouton.add(boite1)

        boite1.show()
        bouton.show()

        self.fenetre.add(bouton)
        self.fenetre.show()

def main():
    gtk.main()
    return 0     

if __name__ == "__main__":
    Bouton()
    main()

De la ligne 12 à la ligne 32, on définit la fonction boite_xpm_etiquette() qui prend en charge la création d'une boite horizontale avec une bordure de 2 (lignes 14-15), puis on y place une image (lignes 25) et une étiquette (ligne 26).

Aux lignes 32-66, on définit la classe Bouton. La méthode constructeur s'étale de la ligne 38 à la ligne 66 ; elle crée une fenêtre (ligne 39), lui donne un titre (ligne 41), connecte les signaux "delete_event" et "destroy" (lignes 44-45). Puis, à la ligne 51, elle crée le bouton sans étiquette, avant de connecter son signal "clicked" à la méthode de rappel salut() (ligne 54). Enfin, elle appelle la fonction boite_xpm_etiquette() à la ligne 57, afin de créer l'image et l'étiquette qu'elle placera dans le bouton à la ligne 60.

La fonction boite_xpm_etiquette() pourrait être utilisée pour placer des images "pixmap" et des étiquettes dans n'importe quel widget pouvant jouer le rôle de conteneur.

Le widget bouton peut émettre les signaux suivants :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
      pressed - émis lorsque le bouton de la souris est enfoncé sur le widget

      released - émis lorsque le bouton de la souris est relâché sur le widget

      clicked - émis lorsque le bouton de la souris est enfoncé puis relâché sur le widget

      enter - émis lorsque le pointeur de la souris arrive sur le widget

      leave - émis lorsque le pointeur de la souris quitte le widget

VI-B. Les boutons à bascule

Le bouton à bascule dérive du bouton simple et lui est donc très similaire. Il a cependant ceci de différent qu'il possède deux états et qu'un clic le fait basculer de l'un à l'autre. Lorsqu'il est enfoncé, un clic le fait remonter. Un autre clic et le voilà de nouveau enfoncé.

Les boutons à bascule sont la base des cases à cocher et des boutons radio, ces derniers héritent donc de beaucoup de leurs appels (nous le signalerons le cas échéant).

Création d'un bouton à bascule :

 
Sélectionnez
  bouton_bascule = gtk.ToggleButton(label=None)

Comme vous pouvez l'imaginer, le fonctionnement de cet appel est identique à celui des boutons normaux. Si aucune étiquette n'est spécifiée, le bouton sera vierge. Dans le cas contraire, le texte donné sera inspecté à la recherche de caractères mnémoniques (préfixés par '_').

Pour récupérer l'état d'un bouton à bascule, ainsi que des boutons radio et des cases à cocher, on fait appel à une construction semblable à l'exemple ci-dessous. Elle teste l'état du bouton en invoquant la méthode get_active() de gtk.ToggleButton. Parmi les signaux émis par les boutons à bascule, celui qui nous intéresse est "toggled". Pour vérifier l'état d'un bouton à bascule, on définira alors un gestionnaire de signal qui se chargera de le capter, puis qui accédera aux attributs de l'objet afin de déterminer son état. La fonction de rappel ressemblera à ceci :

 
Sélectionnez
1.
2.
3.
4.
5.
  def fct_rappel_bascule(widget, donnees):
      if widget.get_active():
          # si le contrôle arrive ici, le bouton à bascule est enfoncé
      else:
          # si le contrôle arrive ici, le bouton à bascule est relevé

Pour forcer l'état d'un bouton à bascule (et de ses descendants les cases à cocher et les boutons radio) on utilise la méthode :

 
Sélectionnez
  bouton_bascule.set_active(is_active)

La méthode ci-dessus peut être utilisée pour imposer l'état d'un bouton à bascule, et de ses descendants, les cases à cocher et les boutons radio. En donnant les valeurs TRUE ou FALSE à l'argument is_active, on indique que le bouton doit être respectivement enfoncé ou relevé. Lors de sa création, un bouton à bascule est en position relevée (FALSE) par défaut.

Notez que lorsque l'on utilise la méthode set_active() et que l'état est effectivement modifié, les signaux "clicked" et "toggled" sont automatiquement émis par le bouton.

 
Sélectionnez
  bouton_bascule.get_active()

Cette méthode renvoie l'état actuel du bouton à bascule sous la forme d'une valeur booléenne TRUE/FALSE.

Le programme boutonsbascule.py donne un exemple courant d'utilisation des boutons à bascule. La figure 6.2 montre la fenêtre obtenue, dans laquelle le deuxième bouton est enfoncé :

Image non disponible
Figure 6.2. Exemple de boutons à bascule

Voici le code source du programme :

 
Sélectionnez
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.
#!/usr/bin/env python

# exemple boutonsbascule.py

import pygtk
pygtk.require('2.0')
import gtk

class BoutonsBascule:
    # Notre fonction de rappel. Le paramètre "donnees"
    # transmis à cette méthode est affiché sur stdout
    def fct_rappel(self, widget, donnees=None):
        print "Le %s a ete %s." % (donnees, ("releve", "enfonce")[widget.get_active()])

    # Cette fonction de rappel quitte le programme
    def evnmt_delete(self, widget, evenement, donnees=None):
        gtk.main_quit()
        return gtk.FALSE

    def __init__(self):
        # Création d'une nouvelle fenêtre.
        self.fenetre = gtk.Window(gtk.WINDOW_TOPLEVEL)

        # On définit le titre de la fenêtre.
        self.fenetre.set_title("Boutons a bascule")

        # On définit un gestionnaire de signal pour "delete_event",
        # qui quitte GTK immédiatement.
        self.fenetre.connect("delete_event", self.evnmt_delete)

        # On fixe la largeur des bordures de la fenêtre.
        self.fenetre.set_border_width(20)

        # Création d'une boite verticale.
        boite_v = gtk.VBox(True, 2)

        # On place la VBox dans la fenêtre principale.
        self.fenetre.add(boite_v)

        # Création du premier bouton.
        bouton = gtk.ToggleButton("bouton a bascule 1")

        # Lorsque l'on change l'état du bouton, la méthode fct_rappel() est
        # appelée, avec un pointeur sur "bouton a bascule 1" comme argument.
        bouton.connect("toggled", self.fct_rappel, "bouton a bascule 1")


        # Insertion du bouton 1 dans le quart supérieur gauche du tableau.
        boite_v.pack_start(bouton, True, True, 2)

        bouton.show()

        # Création du deuxième bouton.

        bouton = gtk.ToggleButton("bouton a bascule 2")

        # Lorsque l'on change l'état du bouton, la méthode fct_rappel() est
        # appelée, avec un pointeur sur "bouton a bascule 2" comme argument.
        bouton.connect("toggled", self.fct_rappel, "bouton a bascule 2")
        # Insertion du bouton 2 dans le quart supérieur droit du tableau.
        boite_v.pack_start(bouton, True, True, 2)

        bouton.show()

        # Création du bouton "Quitter".
        bouton = gtk.Button("Quitter")

        # Lorsque l'on clique sur le bouton, la fonction mainquit() est
        # appelée et le programme se termine.
        bouton.connect("clicked", lambda wid: gtk.main_quit())

        # Insertion du bouton "Quitter" dans les deux quarts inférieurs du tableau.
        boite_v.pack_start(bouton, True, True, 2)

        bouton.show()
        boite_v.show()
        self.fenetre.show()

def main():
    gtk.main()
    return 0       
 
if __name__ == "__main__":
    BoutonsBascule()
    main()

Les parties intéressantes sont les lignes 12-13, qui définissent la méthode fct_rappel() chargée d'afficher le nom et l'état du bouton à bascule quand celui-ci voit son état modifié, et les lignes 45 et 59, qui connectent le signal "toggled" des deux boutons à cette même méthode.

VI-C. Les cases à cocher

Les cases à cocher héritent de nombreuses propriétés et méthodes des boutons à bascule vus précédemment. Leur aspect est cependant différent : il ne s'agit plus de boutons avec du texte à l'intérieur, mais de petits carrés portant le texte à leur droite. Elles servent souvent pour activer/désactiver des options dans les applications.

La méthode de création est semblable à celle des boutons normaux :

 
Sélectionnez
  case_a_cocher = gtk.CheckButton(label=None)

Si l'argument label est fourni, la méthode crée une case à cocher avec une étiquette à son côté. Le texte donné sera inspecté à la recherche de caractères mnémoniques (préfixés par '_').

Les opérations de vérification et de définition de l'état des cases à cocher sont identiques à celles des boutons à bascule.

Le programme casesacocher.py donne un exemple d'utilisation des cases à cocher. La figure 6.3 montre la fenêtre obtenue :

Image non disponible
Figure 6.3. Exemple de cases à cocher

Voici le code source du programme casesacocher.py :

 
Sélectionnez
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.
#!/usr/bin/env python

# exemple casesacocher.py

import pygtk
pygtk.require('2.0')
import gtk
 
class Casesacocher:
    # Notre fonction de rappel. Le paramètre "donnees"
    # transmis a cette méthode est affiché sur stdout
    def fct_rappel(self, widget, donnees=None):
        print "La %s a ete %s." % (donnees, ("desactivee", "activee")[widget.get_active()])

    # Cette fonction de rappel quitte le programme
    def evnmt_delete(self, widget, evenement, donnees=None):
        gtk.main_quit()
        return gtk.FALSE

    def __init__(self):
        # Création d'une nouvelle fenêtre.
        self.fenetre = gtk.Window(gtk.WINDOW_TOPLEVEL)

        # On définit le titre de la fenêtre.
        self.fenetre.set_title("Cases a cocher")

        # On définit un gestionnaire de signal pour "delete_event",
        # qui quitte GTK immédiatement.
        self.fenetre.connect("delete_event", self.evnmt_delete)

        # On fixe la largeur des bordures de la fenêtre.
        self.fenetre.set_border_width(20)

        # Création d'une boite verticale.
        boite_v = gtk.VBox(True, 2)

        # On place la VBox dans la fenêtre principale.
        self.fenetre.add(boite_v)

        # Création du premier bouton.
        bouton = gtk.CheckButton("case a cocher 1")

        # Lorsque l'on change l'état du bouton, la méthode fct_rappel() est
        # appelée, avec un pointeur sur "case à cocher 1" comme argument.
        bouton.connect("toggled", self.fct_rappel, "case a cocher 1")


        # Insertion du bouton 1 dans le quart supérieur gauche du tableau.
        boite_v.pack_start(bouton, True, True, 2)

        bouton.show()

        # Création du deuxième bouton.

        bouton = gtk.CheckButton("case a cocher 2")

        # Lorsque l'on change l'état du bouton, la méthode fct_rappel() est
        # appelée, avec un pointeur sur "case a cocher 2" comme argument.
        bouton.connect("toggled", self.fct_rappel, "case a cocher 2")
        # Insertion du bouton 2 dans le quart supérieur droit du tableau.
        boite_v.pack_start(bouton, True, True, 2)

        bouton.show()

        # Création du bouton "Quitter".
        bouton = gtk.Button("Quitter")

        # Lorsque l'on clique sur le bouton, la fonction mainquit() est
        # appelée et le programme se termine.
        bouton.connect("clicked", lambda wid: gtk.main_quit())

        # Insertion du bouton "Quitter" dans les deux quarts inférieurs du tableau.
        boite_v.pack_start(bouton, True, True, 2)

        bouton.show()
        boite_v.show()
        self.fenetre.show()

def main():
    gtk.main()
    return 0       
 
if __name__ == "__main__":
    Casesacocher()
    main()

VI-D. Les boutons radio

Les boutons radio sont similaires aux cases à cocher, à ceci près qu'on les assemble par groupes, dans lesquels un seul bouton peut être sélectionné/enfoncé à la fois. Ils sont très pratiques pour les parties de vos applications où l'on doit effectuer une sélection parmi une courte liste.

La création d'un nouveau bouton radio s'effectue avec l'appel suivant :

 
Sélectionnez
  bouton_radio = gtk.RadioButton(group=None, label=None)

Vous aurez remarqué le nouvel argument group pour cet appel. En effet, pour fonctionner correctement, les boutons radio nécessitent un groupe. Lors du premier appel à gtk.RadioButton(), l'argument group doit valoir None, ce qui créera un nouveau groupe comptant comme seul membre le nouveau bouton radio.

Pour ajouter de nouveaux boutons radio à un groupe, transmettez lors de vos appels à gtk.RadioButton() une référence à un bouton radio du groupe.

Si vous avez spécifié un texte pour l'argument label, il sera passé en revue à la recherche de caractères mnémoniques (préfixés par '_').

Pour définir explicitement le bouton qui doit être sélectionné par défaut, utilisez :

 
Sélectionnez
  bouton_radio.set_active(is_active)

Cette méthode est décrite dans la section sur les boutons à bascule et fonctionne exactement de la même manière. Une fois que les boutons radio sont assemblés en un groupe, on ne pourra sélectionner qu'un seul bouton de ce groupe à la fois. Si l'utilisateur clique sur un bouton radio, puis sur un autre, alors le premier émettra un signal "toggled" pour informer qu'il a été désactivé, avant que le second l'imite, pour signaler cette fois qu'il vient d'être activé.

Le programme exemple boutonsradio.py crée un groupe de trois boutons radio. La figure 6.4 montre la fenêtre obtenue :

Image non disponible
Figure 6.4. Exemple de boutons radio

Voici le code source du programme :

 
Sélectionnez
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.
#!/usr/bin/env python

# exemple boutonsradio.py

import pygtk
pygtk.require('2.0')
import gtk

class BoutonsRadio:
    def fct_rappel(self, widget, donnees=None):
        print "Le %s a ete %s." % (donnees, ("desactive", "active")[widget.get_active()])

    def quitter_pgm(self, widget, evenement, donnees=None):
        gtk.main_quit()
        return False

    def __init__(self):
        self.fenetre = gtk.Window(gtk.WINDOW_TOPLEVEL)

        self.fenetre.connect("delete_event", self.quitter_pgm)

        self.fenetre.set_title("Boutons radio")
        self.fenetre.set_border_width(0)

        boite1 = gtk.VBox(False, 0)
        self.fenetre.add(boite1)
        boite1.show()

        boite2 = gtk.VBox(False, 10)
        boite2.set_border_width(10)
        boite1.pack_start(boite2, True, True, 0)
        boite2.show()

        bouton = gtk.RadioButton(None, "bouton radio 1")
        bouton.connect("toggled", self.fct_rappel, "bouton radio 1")
        boite2.pack_start(bouton, True, True, 0)
        bouton.show()

        bouton = gtk.RadioButton(bouton, "bouton radio 2")
        bouton.connect("toggled", self.fct_rappel, "bouton radio 2")
        bouton.set_active(True)
        boite2.pack_start(bouton, True, True, 0)
        bouton.show()

        bouton = gtk.RadioButton(bouton, "bouton radio 3")
        bouton.connect("toggled", self.fct_rappel, "bouton radio 3")
        boite2.pack_start(bouton, True, True, 0)
        bouton.show()

        separateur = gtk.HSeparator()
        boite1.pack_start(separateur, False, True, 0)
        separateur.show()

        boite2 = gtk.VBox(False, 10)
        boite2.set_border_width(10)
        boite1.pack_start(boite2, False, True, 0)
        boite2.show()

        bouton = gtk.Button("fermer")
        bouton.connect_object("clicked", self.quitter_pgm, 
                              self.fenetre, None)
        boite2.pack_start(bouton, True, True, 0)
        bouton.set_flags(gtk.CAN_DEFAULT)
        bouton.grab_default()
        bouton.show()
        self.fenetre.show()

def main():
    gtk.main()
    return 0        

if __name__ == "__main__":
    BoutonsRadio()
    main()

Le code est assez explicite. Aux lignes 63-64, on fait du bouton "fermer" le widget par défaut, de sorte qu'en appuyant sur la touche "Entrée" lorsque la fenêtre est active, il émette le signal "clicked".


précédentsommairesuivant

Copyright © 2005 John Finlay. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.