FAQ PythonConsultez toutes les FAQ

Nombre d'auteurs : 16, nombre de questions : 313, dernière mise à jour : 10 juillet 2017  Ajouter une question

 

Cette FAQ a été réalisée à partir des questions posées sur le forum Python complétées par d'autres questions qui pouvaient nous sembler intéressantes de traiter. Toutefois il se peut que les réponses apportées contiennent des erreurs, imprécisions ... Vous pouvez dans ce cas contacter un des membres de la rédaction pour lui faire part de vos remarques.

L'équipe Python de Developpez.


Sommaire36 Q/R Python et Tkinter pour passer son Bac !Questions Tkinter (12)
précédent sommaire suivant
 

R : Avez-vous mis mainloop() en fin de script ?

Il y a de fortes chances pour que vous ayez oublié de lancer la boucle événementielle principale de Tkinter en bout de script.

Exemple :

Code python : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/usr/bin/env python3 
# -*- coding: utf-8 -*- 
  
from tkinter import * 
  
fenetre = Tk() 
  
# mettez ici tout le code dont vous avez besoin 
  
Label(fenetre, text="Essai fenêtre").pack(pady=20, padx=10) 
  
Button(fenetre, text="Quitter", command=fenetre.destroy).pack(pady=5) 
  
# /!\ n'oubliez pas de finir avec la boucle principale /!\ 
  
fenetre.mainloop()

Je veux comprendre :

Une librairie graphique - appelée aussi GUI pour Graphical User Interface - fonctionne sur le principe des interactions événementielles entre l'utilisateur humain et la machine. Par exemple, si on veut exécuter une action donnée, on va cliquer sur un bouton qui se trouve dans la fenêtre programme. Le bouton va en réalité déclencher un événement qui sera ensuite associé à la fonctionnalité que l'on veut utiliser. De même, quand on redimensionne une fenêtre, celle-ci notifie un événement « changement de taille » à la librairie graphique afin que cette dernière puisse redessiner la fenêtre à sa nouvelle taille. Comme tout fonctionne à coups d'événements dans un environnement graphique, il faut une boucle principale qui capture tous ces événements et qui les traite ensuite.

Pensez à mettre fenetre.mainloop() en fin de script.

Pour Tkinter, cette boucle événementielle principale s'appelle mainloop(). Il faut donc systématiquement l'appeler en fin de script, car une fois cette boucle principale lancée, tout le code qui sera écrit ensuite ne pourra s'exécuter que lorsque la boucle principale prendra fin, c'est-à-dire lorsque vous aurez fermé la fenêtre principale de votre programme.

Par exemple :

Code python : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/usr/bin/env python3 
# -*- coding: utf-8 -*- 
  
from tkinter import * 
  
fenetre = Tk() 
  
# mettez ici tout le code dont vous avez besoin 
  
Label(fenetre, text="Essai fenêtre").pack(pady=20, padx=10) 
  
Button(fenetre, text="Quitter", command=fenetre.destroy).pack(pady=5) 
  
# /!\ n'oubliez pas de finir avec la boucle principale /!\ 
  
fenetre.mainloop() 
  
# ce code ne s'exécutera que lorsque la fenêtre principale sera fermée 
  
print("fin du programme")

Mis à jour le 29 août 2014

Plus d'infos sur cette page de tutoriel.

R : Une seule fenêtre Tk() par programme !

Vous ne devez déclarer qu'une seule fenêtre Tk() par programme, puis utiliser Toplevel() pour toutes les autres fenêtres que vous voulez afficher.

Exemple :

Code python : 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
#!/usr/bin/env python3 
# -*- coding: utf-8 -*- 
  
from tkinter import * 
  
def nouvelle_fenetre (): 
    """ 
        cette fonction crée une nouvelle fenêtre fille à chaque fois 
        qu'on clique sur le bouton correspondant 
    """ 
  
    global fenetre_fille 
  
    # ceci est une fenêtre fille (Toplevel) 
    # elle sera automatiquement détruite lorsque vous quitterez le 
    # programme en fermant la fenêtre principale 
  
    fenetre_fille = Toplevel() 
  
    Label(fenetre_fille, text="Hello good people!").pack(pady=20, padx=10) 
  
    Button(fenetre_fille, text="Quitter", command=fenetre_fille.destroy).pack(pady=5) 
  
# end def 
  
# ceci est la fenêtre principale du programme (Tk) 
  
fenetre = Tk() 
  
fenetre.title("Fenêtre principale") 
  
# mettez ici tout le code dont vous avez besoin 
  
Label(fenetre, text="Cliquez sur le bouton").pack(pady=20, padx=10) 
  
Button(fenetre, text="Nouvelle fenêtre fille", command=nouvelle_fenetre).pack(pady=5, padx=10) 
  
Button(fenetre, text="Quitter", command=fenetre.destroy).pack(pady=5) 
  
# /!\ n'oubliez pas de finir avec la boucle principale /!\ 
  
fenetre.mainloop()

Je veux comprendre :

Pour faire simple, lorsque vous appelez Tk(), vous appelez une fenêtre principale de programme. Or, pour un programme donné, il ne peut y avoir qu'une et une seule fenêtre principale, toutes les autres étant forcément des fenêtres secondaires, c'est-à-dire des Toplevel().

Une seule déclaration de Tk() pour l'ensemble du programme. On utilise Toplevel() pour les fenêtres secondaires.

C'est pourquoi vous êtes obligé(e) de commencer votre programme en appelant au moins la fenêtre principale Tk(), suivie ensuite - si vous en avez besoin - d'autres fenêtres secondaires Toplevel().

Notez aussi que durant le déroulement de votre programme, vous pouvez fermer autant de fenêtres secondaires Toplevel() que vous voulez, indépendamment les unes des autres, alors que le simple fait de fermer la fenêtre principale Tk() provoque, lui, la fermeture automatique de toutes les fenêtres secondaires de même que l'arrêt du programme graphique. Ce n'est donc pas du tout le même comportement entre une fenêtre principale Tk() et une fenêtre secondaire Toplevel().

Mis à jour le 29 août 2014

Plus d'infos sur cette page de tutoriel.

R : Vous n'avez pas la même version de Python.

Et donc pas la même adaptation de Tkinter non plus.

Prenez l'habitude d'installer et Python2 et Python3 sur votre machine quand vous voulez faire des essais avec des scripts provenant d'autres personnes.

Lien de téléchargement : https://www.python.org/downloads/ (en anglais).

Je veux comprendre :

La librairie graphique Tkinter a été entièrement remaniée dans son organisation entre les versions Python2 et Python3. Ainsi, un script écrit pour Python2 utilise plusieurs modules affiliés à Tkinter, mais néanmoins distincts, alors que pour un script écrit pour Python3, tous les modules ont été regroupés sous un seul package nommé tkinter. Chaque version a ses propres modules et sa propre organisation interne qu'elle ne partage pas avec l'autre version.

Sous Python2, on appelle les modules distincts, affiliés à Tkinter, comme ceci :

Code python : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
#!/usr/bin/env python 
# -*- coding: utf-8 -*- 
  
import Tkinter 
import ttk 
import Tix 
import tkFont 
import ScrolledText 
import tkMessageBox 
import tkFileDialog 
import tkSimpleDialog 
import tkCommonDialog 
import tkColorChooser

Alors que sous Python3, on appelle les modules tkinter équivalents comme ceci :

Code python : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
#!/usr/bin/env python3 
# -*- coding: utf-8 -*- 
  
import tkinter 
import tkinter.ttk 
import tkinter.tix 
import tkinter.font 
import tkinter.scrolledtext 
import tkinter.messagebox 
import tkinter.filedialog 
import tkinter.simpledialog 
import tkinter.commondialog 
import tkinter.colorchooser

Note : dans la mesure du possible, mettez toujours vos mentions import en tout premier dans le script, avant toute autre instruction.

Mis à jour le 29 août 2014

Plus d'infos sur cette page de tutoriel.

R : Vous avez affecté None à votre variable objet.

Séparez la définition de l'objet de la méthode .pack(), .grid() ou .place() que vous utilisez.

Le grand classique du genre :

Code python : 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
#!/usr/bin/env python3 
# -*- coding: utf-8 -*- 
  
from tkinter import * 
  
fenetre = Tk() 
  
# voici l'erreur LA PLUS RÉPANDUE QUI SOIT chez les débutants tkinter : 
  
canvas = Canvas(fenetre, bg="ivory", height=50).pack() # <-- pack() retourne None donc canvas = None 
  
print("canvas =", repr(canvas)) 
  
# il faut d'abord déclarer l'objet 
  
canvas = Canvas(fenetre, bg="sky blue", height=50) 
  
# ensuite seulement appliquer .pack() 
  
canvas.pack() 
  
print("canvas =", repr(canvas)) 
  
btn_quitter = Button(fenetre, text="Quitter", command=fenetre.destroy) 
  
btn_quitter.pack() 
  
print("btn_quitter =", repr(btn_quitter)) 
  
fenetre.mainloop()

Résultat console :

Code shell : Sélectionner tout
1
2
3
canvas = None 
canvas = <tkinter.Canvas object at 0x7f3550ad8d68> 
btn_quitter = <tkinter.Button object at 0x7f3550ad8dd8>

Ce sujet est expliqué plus en détail dans cette page de tutoriel.

Mis à jour le 29 août 2014

R : Vous avez mélangé des pack() avec des grid() ou des place() pour un même widget conteneur.

N'utilisez qu'une seule méthode : c'est ou pack() ou grid() ou place() - mais surtout pas un mix - au sein d'un même widget conteneur. Évitez les panachages autant que possible. Prenez même l'habitude de n'utiliser qu'une seule méthode tout au long de votre programme.

Je veux comprendre :

Les widgets Tkinter sont tous dotés de trois gestionnaires d'affichage - appelés geometry managers dans la doc officielle - pack(), grid() et place(), chacun ayant sa propre façon d'afficher les widgets, mais aucun n'ayant priorité sur les deux autres.

Ainsi, lorsque vous placez dans un même widget conteneur - appelé aussi widget parent ou master dans certaines documentations - des widgets que vous placez tantôt en appelant pack(), tantôt en appelant grid() ou encore en appelant place(), vous provoquez un conflit d'affichage entre tous ces widgets, chaque gestionnaire voulant placer son widget, mais ne pouvant pas griller la politesse aux autres gestionnaires d'affichage.

Du coup, le système tourne en rond indéfiniment et vous avez l'impression que votre programme s'est planté avec ce qu'on appelle généralement un freeze - écran gelé, plus rien ne se passe.

Depuis la version Tcl/Tk 8.6 sur laquelle s'appuie Tkinter, un système de sécurité a été ajouté et déclenche un message d'erreur en cas de conflit d'affichage, ce qui est beaucoup plus confortable pour le débogage des scripts.

Si vous installez les dernières versions en date de Python2 et de Python3, vous devriez avoir aussi cette petite nouveauté ô combien appréciable.

Lien de téléchargement : https://www.python.org/downloads/ (en anglais).

Ce sujet est expliqué plus en détail dans cette page de tutoriel.

Mis à jour le 30 août 2014

R : Vous avez affecté la valeur retour de la fonction et non pas la fonction elle-même.

Enlevez les parenthèses d'appel de fonction et ne gardez que le nom de la fonction.

Cas typique :

Code python : 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
#!/usr/bin/env python3 
# -*- coding: utf-8 -*- 
  
from tkinter import * 
  
def convertir (): 
    resultat.set(bin(int(entree.get()))) 
# end def 
  
fenetre = Tk() 
Label(fenetre, text="Entrez un nombre entier:").pack() 
entree = Entry(fenetre) 
entree.pack() 
Label(fenetre, text="Résultat de la conversion:").pack() 
resultat = StringVar() 
Label(fenetre, textvariable=resultat).pack() 
  
# command=callback attend un NOM de fonction 
# et NON PAS la valeur retour d'une fonction 
  
Button(fenetre, text="Convertir", command=convertir()).pack() # ERREUR! 
  
# remplacez par : 
  
Button(fenetre, text="Convertir", command=convertir).pack() # CORRECT 
  
fenetre.mainloop()

Résultat console :

Code shell : Sélectionner tout
1
2
3
4
5
6
Traceback (most recent call last): 
  File "./forum.py", line 21, in <module> 
    Button(fenetre, text="Convertir", command=convertir()).pack() # ERREUR! 
  File "./forum.py", line 7, in convertir 
    resultat.set(bin(int(entree.get()))) 
ValueError: invalid literal for int() with base 10: ''

Je veux comprendre :

Le paramètre command que l'on trouve dans l'objet Tkinter Button(), comme chez d'autres objets encore, attend le nom d'une fonction - dite callback ou fonction de rappel - et non pas la valeur retour d'une fonction appelée sur place.

En effet, c'est l'objet lui-même qui appellera la fonction callback en temps voulu, vous n'avez donc pas à appeler cette fonction au moment de l'assigner au paramètre command.

Ce sujet est expliqué plus en détail dans cette page de tutoriel.

Mis à jour le 30 août 2014

R : Vous lancez très certainement une boucle qui ne s'inscrit pas dans la boucle événementielle de Tkinter.

Il faut étaler votre boucle dans le temps avec w.after().

Exemple, au lieu d'écrire :

Code python : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
def compter (): 
    # on efface la sortie console 
    display.delete("1.0", END) 
    # et on compte... 
    for i in range(10): 
        # petit message censé s'afficher PENDANT le comptage... 
        display.insert(END, "valeur actuelle : {}\n".format(i)) 
        # on marque une pause exprès... 
        time.sleep(0.200) 
    # end for 
# end def

Ce qui schématiquement revient à faire :



Écrivez plutôt :

Code python : 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
def compter (): 
    # on désactive le bouton 'compter' 
    bouton_compter.configure(state=DISABLED) 
    # on efface la sortie console 
    display.delete("1.0", END) 
    # et on compte... 
    boucle_tkinter(0, 10) 
# end def 
  
def boucle_tkinter (debut, fin): 
    # petit message censé s'afficher PENDANT le comptage... 
    display.insert(END, "valeur actuelle : {}\n".format(debut)) 
    # màj données 
    debut += 1 
    # on étale dans le temps avec w.after() 
    if debut < fin: 
        # on marque une pause exprès... 
        fenetre.after(200, boucle_tkinter, debut, fin) 
    # c'est fini 
    else: 
        # on réactive le bouton 'compter' 
        bouton_compter.configure(state=NORMAL) 
    # end if 
# end def

Ce qui schématiquement revient à faire :



Ce sujet est expliqué plus en détail dans cette page de tutoriel.

Mis à jour le 30 août 2014

R : Proposez-leur aussi d'ajouter PyQT et PyGTK, tant qu'à faire !

Peut-être qu'avec quatre environnements graphiques, ils finiront par obtenir en quarante ans ce que vous ferez allègrement avec un seul environnement graphique en un mois ?

Mixer plusieurs librairies graphiques est tout bonnement une très mauvaise idée : concentrez-vous sur Tkinter, apprenez tout d'abord à bien le maîtriser et vous songerez à passer aux vitesses supérieures ensuite seulement.

Connaître Tkinter sur le bout des doigts n'est jamais peine perdue : cette librairie vous dépannera encore bien des fois durant votre carrière professionnelle…

Je veux comprendre :

Chaque librairie, chaque environnement graphique a ses propres règles et son propre fonctionnement. De plus, la plupart des librairies graphiques implémentent une boucle événementielle principale - c'est le cas de Tkinter, de PyGTK et de PyQT, alors que Pygame oblige à écrire sa propre boucle.

Sachant cela, comment allez-vous résoudre le dilemme suivant : si j'utilise au moins deux librairies graphiques en même temps dans mon script, quelle boucle principale dois-je appeler, sachant que si j'en appelle une, je ne peux pas appeler l'autre (ce sont des boucles, hein, pas des passoires) ?

Mis à jour le 30 août 2014

Plus d'infos sur cette page de tutoriel.

R : Tkinter permet de gérer des actions et des animations étalées dans le temps.

Utilisez des fonctions reposant sur w.after() qui s'appellent elles-mêmes en boucle.

Voici comment fonctionne schématiquement une boucle Tkinter :



Documentation Tkinter w.after() : http://infohost.nmt.edu/tcc/help/pub...universal.html (en anglais).

Ce sujet est expliqué plus en détail dans cette page de tutoriel avec en cadeau BONUS le jeu "Terrain miné" qui vous est offert gracieusement (à ne pas confondre avec le jeu "Mines" classique).

Mis à jour le 30 août 2014

R : Utilisez une fermeture dans le paramètre command de vos boutons avec la valeur souhaitée.

Une fermeture est une fonction qui retourne en résultat une autre fonction.

Un bon exemple valant mille mots, voici un cas d'école : une interface GUI de calculette.

Code python : 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
90
91
92
93
94
95
96
97
#!/usr/bin/env python3 
# -*- coding: utf-8 -*- 
  
from tkinter import * 
  
# on définit une fermeture 
def key_pad (key_value): 
    # on définit ici la vraie fonction qui fait le traitement attendu; 
    # comme cette fonction sera appelée par le bouton cliquable 
    # elle ne prend AUCUN ARGUMENT dans sa définition; 
    # en revanche, elle va se servir des arguments stockés dans 
    # la fermeture (c'est tout l'intérêt du truc); 
    def mon_traitement (): 
        # on exploite l'argument stocké par la fermeture 
        # touche pavé numérique '0' à '9': 
        if key_value in range(10): 
            # on ajoute un chiffre à l'affichage 
            display.set(display.get() + str(key_value)) 
        # touche 'AC' - 'All Clear' - tout effacer 
        elif key_value == 'AC': 
            # on efface tout 
            display.set("") 
        # ...etc... 
        # end if 
    # end def 
    # retourne une fonction en résultat 
    return mon_traitement 
# end def 
  
# on crée la fenêtre principale 
fenetre = Tk() 
fenetre.title("Calculette") 
fenetre.resizable(width=False, height=False) 
  
# on ajoute des widgets 
display = StringVar() 
Label( 
    fenetre, 
    textvariable=display, 
    anchor=E, 
    bg="pale green", 
    font="sans 14 bold", 
    relief=SUNKEN, 
    width=10, 
).pack(padx=5, pady=5) 
  
# on crée un conteneur à boutons 
frame = Frame(fenetre) 
frame.pack(padx=5, pady=5) 
  
# options de grid() 
opts = dict(sticky=NW+SE) 
  
# on ajoute les boutons utilisant la fermeture 
Button( 
    frame, 
    text="C", 
    command=key_pad('C') 
).grid(row=0, column=0, **opts) 
  
Button( 
    frame, 
    text="AC", 
    command=key_pad('AC') 
).grid(row=0, column=1, columnspan=2, **opts) 
  
Button(frame, text="9", command=key_pad(9)).grid(row=1, column=2, **opts) 
Button(frame, text="8", command=key_pad(8)).grid(row=1, column=1, **opts) 
Button(frame, text="7", command=key_pad(7)).grid(row=1, column=0, **opts) 
Button(frame, text="6", command=key_pad(6)).grid(row=2, column=2, **opts) 
Button(frame, text="5", command=key_pad(5)).grid(row=2, column=1, **opts) 
Button(frame, text="4", command=key_pad(4)).grid(row=2, column=0, **opts) 
Button(frame, text="3", command=key_pad(3)).grid(row=3, column=2, **opts) 
Button(frame, text="2", command=key_pad(2)).grid(row=3, column=1, **opts) 
Button(frame, text="1", command=key_pad(1)).grid(row=3, column=0, **opts) 
  
Button( 
    frame, 
    text="0", 
    command=key_pad(0) 
).grid(row=4, column=0, columnspan=2, **opts) 
  
Button( 
    frame, 
    text=".", 
    command=key_pad('.') 
).grid(row=4, column=2, **opts) 
  
# on ajoute un bouton quitter 
Button( 
    fenetre, 
    text="Quitter", 
    command=fenetre.destroy, 
).pack(padx=5, pady=5) 
  
# on lance la boucle principale 
fenetre.mainloop()

Ce sujet est expliqué plus en détail dans cette page de tutoriel.

Mis à jour le 30 août 2014

R : Oui, c'est le principe de la fonction dispatch.

Il suffit d'appeler une fonction qui s'occupera de relayer les commandes de l'objet Scrollbar() aux deux canevas.

Exemple :

Code python : 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
#!/usr/bin/env python3 
# -*- coding: utf-8 -*- 
  
from tkinter import * 
  
# on crée une fonction de dispatch 
def dispatch_yview (*args): 
    """ 
        cette fonction dispatche les commandes de la scrollbar 
        VERTICALE entre les deux canevas; 
    """ 
    canvas1.yview(*args) 
    canvas2.yview(*args) 
# end def 
  
# on crée la fenêtre principale 
fenetre = Tk() 
  
# on ajoute des widgets 
  
# options de texte 
txt_options = dict( 
    text="Hello, world!", 
    font="sans 16 bold", 
    fill="indian red", 
) 
  
# canvas 1 
canvas1 = Canvas(fenetre, bg="pale goldenrod", width=200, height=200) 
canvas1.create_text(100, 100, **txt_options) 
canvas1.grid(row=0, column=0, sticky=NW+SE) 
  
# canvas 2 
canvas2 = Canvas(fenetre, bg="sky blue", width=200, height=200) 
canvas2.create_text(100, 100, **txt_options) 
canvas2.grid(row=0, column=1, sticky=NW+SE) 
  
# horizontal scrollbar canvas 1 
hbar1 = Scrollbar(fenetre, orient=HORIZONTAL) 
hbar1.grid(row=1, column=0, sticky=EW) 
  
# horizontal scrollbar canvas 2 
hbar2 = Scrollbar(fenetre, orient=HORIZONTAL) 
hbar2.grid(row=1, column=1, sticky=EW) 
  
# VERTICAL scrollbar 
vbar = Scrollbar(fenetre, orient=VERTICAL) 
vbar.grid(row=0, column=2, sticky=NS) 
  
# on rend les canevas redimensionnables 
fenetre.rowconfigure(0, weight=1) 
fenetre.columnconfigure(0, weight=1) 
fenetre.columnconfigure(1, weight=1) 
  
# on connecte les scrollbars aux canevas 
canvas1.configure( 
    xscrollcommand=hbar1.set, 
    yscrollcommand=vbar.set, 
    scrollregion=(0, 0, 800, 600), 
) 
canvas2.configure( 
    xscrollcommand=hbar2.set, 
    yscrollcommand=vbar.set, 
    scrollregion=(0, 0, 800, 600), 
) 
hbar1.configure(command=canvas1.xview) 
hbar2.configure(command=canvas2.xview) 
  
# on relie la fonction de dispatch ici 
vbar.configure(command=dispatch_yview) 
  
# on lance la boucle principale 
fenetre.mainloop()

Ce sujet est expliqué plus en détail dans cette page de tutoriel.

Mis à jour le 30 août 2014

R : Si, mais à condition d'avoir une version récente de Python.

Et donc de Tkinter ! Vous devez avoir au moins Tcl/Tk 8.5 pour en bénéficier.

Vous pouvez utiliser les objets Scrollbar() de la librairie additionnelle ttk fournie avec Tkinter.

Exemple Python2 :

Code python : 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
#!/usr/bin/env python 
# -*- coding: utf-8 -*- 
  
from Tkinter import * 
import ttk 
  
# on crée la fenêtre principale 
fenetre = Tk() 
  
# on crée un conteneur pour bien présenter 
frame = Frame(fenetre) 
frame.pack(expand=1, fill=BOTH, padx=2, pady=2) 
  
# on ajoute des widgets 
canvas = Canvas(frame, bg="white", width=200, height=150) 
canvas.create_text(100, 75, text="Hello good people!") 
hbar = ttk.Scrollbar(frame, orient=HORIZONTAL) 
vbar = ttk.Scrollbar(frame, orient=VERTICAL) 
  
# on ajoute une petite poignée de redimensionnement 
# histoire de faire joli 
sizegrip = ttk.Sizegrip(frame) 
  
# on connecte les scrollbars au canevas 
canvas.configure( 
    xscrollcommand=hbar.set, 
    yscrollcommand=vbar.set, 
    scrollregion=(0, 0, 800, 600), 
) 
hbar.configure(command=canvas.xview) 
vbar.configure(command=canvas.yview) 
  
# on place les widgets avec grid() 
canvas.grid(row=0, column=0, sticky=NW+SE) 
hbar.grid(row=1, column=0, sticky=EW) 
vbar.grid(row=0, column=1, sticky=NS) 
sizegrip.grid(row=1, column=1) 
  
# on rend le canevas redimensionnable 
frame.rowconfigure(0, weight=1) 
frame.columnconfigure(0, weight=1) 
  
# on lance la boucle principale 
fenetre.mainloop()

Exemple Python3 :

Code python : 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
#!/usr/bin/env python3 
# -*- coding: utf-8 -*- 
  
from tkinter import * 
from tkinter import ttk 
  
# on crée la fenêtre principale 
fenetre = Tk() 
  
# on crée un conteneur pour bien présenter 
frame = Frame(fenetre) 
frame.pack(expand=1, fill=BOTH, padx=2, pady=2) 
  
# on ajoute des widgets 
canvas = Canvas(frame, bg="white", width=200, height=150) 
canvas.create_text(100, 75, text="Hello good people!") 
hbar = ttk.Scrollbar(frame, orient=HORIZONTAL) 
vbar = ttk.Scrollbar(frame, orient=VERTICAL) 
  
# on ajoute une petite poignée de redimensionnement 
# histoire de faire joli 
sizegrip = ttk.Sizegrip(frame) 
  
# on connecte les scrollbars au canevas 
canvas.configure( 
    xscrollcommand=hbar.set, 
    yscrollcommand=vbar.set, 
    scrollregion=(0, 0, 800, 600), 
) 
hbar.configure(command=canvas.xview) 
vbar.configure(command=canvas.yview) 
  
# on place les widgets avec grid() 
canvas.grid(row=0, column=0, sticky=NW+SE) 
hbar.grid(row=1, column=0, sticky=EW) 
vbar.grid(row=0, column=1, sticky=NS) 
sizegrip.grid(row=1, column=1) 
  
# on rend le canevas redimensionnable 
frame.rowconfigure(0, weight=1) 
frame.columnconfigure(0, weight=1) 
  
# on lance la boucle principale 
fenetre.mainloop()

Ce sujet est expliqué plus en détail dans cette page de tutoriel.

Mis à jour le 30 août 2014

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 © 2017 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.

 
Contacter le responsable de la rubrique Python