Widget Text de Tkinter - créer un éditeur multiligne

Alfred Jacques .

27 octobre 2026

Code Python utilisant tkinter pour créer une fenêtre avec le texte "Tkinter c'est fantastique...".

Un champ de texte qui accepte plusieurs lignes, permet la mise en forme et peut même servir de mini éditeur de code ne demande que quelques lignes de Python. Le widget Text de Tkinter, souvent désigné par l’expression tkinter text dans les exemples anglophones, offre justement cette souplesse. Voici comment le créer, lire son contenu, le styliser, lui ajouter une barre de défilement et éviter les erreurs les plus courantes.

Les points essentiels pour exploiter Text efficacement

  • Multiligne : Text convient aux notes, journaux, éditeurs et zones de commentaire.
  • Index précis : 1.0 désigne la première ligne et le premier caractère.
  • Méthodes indispensables : insert(), get() et delete() couvrent les opérations de base.
  • Mise en forme : les tags permettent d’appliquer plusieurs styles dans une même zone.
  • Bonne pratique : utilisez end-1c pour récupérer le texte sans le saut de ligne final ajouté par Tkinter.

Comprendre le widget Text de Tkinter

Text est une zone d’édition capable d’afficher et de modifier du texte sur plusieurs lignes. Contrairement à Label, il accepte la saisie utilisateur, et contrairement à Entry, il convient aux contenus longs comme une note, un message ou un fichier source.

Je le choisis dès qu’un utilisateur doit écrire plus d’une ligne. Pour une adresse e-mail ou un nom, Entry reste plus simple. Pour une description, un commentaire ou un éditeur, Text est nettement plus adapté.

Widget Usage principal Particularité
Label Afficher une information Non modifiable
Entry Saisir une courte valeur Une seule ligne
Text Rédiger ou afficher un contenu long Multiligne et personnalisable

Son système d’index mérite une attention particulière. 1.0 représente le début de la première ligne, tandis que 2.5 pointe vers le sixième caractère de la deuxième ligne. Les lignes commencent à 1, mais les caractères commencent à 0.

Créer une zone Text fonctionnelle

La version minimale tient en quelques instructions. L’option wrap contrôle le retour à la ligne automatique, tandis que height et width indiquent une taille approximative en lignes et en caractères.

import tkinter as tk

fenetre = tk.Tk()
fenetre.title("Éditeur Tkinter")
fenetre.geometry("650x400")

zone = tk.Text(
    fenetre,
    height=15,
    width=70,
    wrap="word",
    font=("Arial", 12),
    padx=10,
    pady=10
)
zone.pack(fill="both", expand=True)

zone.insert("1.0", "Écrivez votre texte ici...")
fenetre.mainloop()

J’utilise généralement fill="both" et expand=True pour que la zone profite de l’espace disponible. Sans ces options, elle reste souvent figée dans un coin de la fenêtre, ce qui donne une interface peu agréable dès que la fenêtre est redimensionnée.

Les options qui changent vraiment l’expérience

  • wrap="word" coupe les lignes entre les mots.
  • wrap="char" autorise une coupure caractère par caractère.
  • wrap="none" conserve les longues lignes et nécessite souvent un défilement horizontal.
  • undo=True active l’historique annuler-rétablir.
  • state="disabled" transforme la zone en affichage non modifiable.
  • font, bg et fg permettent d’adapter rapidement son apparence.

Pour une interface destinée à la lecture, je préfère state="disabled" plutôt qu’un widget totalement différent. Il conserve les fonctions de sélection et de copie, tout en empêchant les modifications accidentelles.

Insérer, lire et supprimer du contenu

Trois méthodes suffisent pour les opérations courantes. insert() ajoute du texte, get() le récupère et delete() le supprime. La combinaison la plus utilisée est zone.get("1.0", "end-1c"), car elle évite de récupérer le saut de ligne final automatique de Tkinter.

import tkinter as tk

fenetre = tk.Tk()
zone = tk.Text(fenetre, width=60, height=12)
zone.pack(padx=12, pady=12)

def ajouter_texte():
    zone.insert("end", "\nNouvelle ligne ajoutée.")

def afficher_texte():
    contenu = zone.get("1.0", "end-1c")
    print(contenu)

def vider_zone():
    zone.delete("1.0", "end")

tk.Button(fenetre, text="Ajouter", command=ajouter_texte).pack()
tk.Button(fenetre, text="Afficher", command=afficher_texte).pack()
tk.Button(fenetre, text="Vider", command=vider_zone).pack()

fenetre.mainloop()

La position "end" signifie la fin logique du contenu, mais elle inclut le caractère de nouvelle ligne placé par le widget. Pour une sauvegarde ou une comparaison de chaînes, end-1c est presque toujours le choix correct.

Travailler avec la sélection

La sélection courante se trouve entre les index sel.first et sel.last. Comme aucune sélection n’existe parfois, il faut intercepter l’exception tk.TclError au lieu de supposer que ces index sont toujours disponibles.

def copier_selection():
    try:
        texte = zone.get("sel.first", "sel.last")
        fenetre.clipboard_clear()
        fenetre.clipboard_append(texte)
    except tk.TclError:
        print("Aucun texte sélectionné.")

Cette approche est pratique pour construire une barre d’outils, mais les raccourcis clavier natifs de Tkinter couvrent déjà une partie des besoins. Je réserve donc les boutons Copier, Couper ou Rechercher aux applications où ces fonctions doivent être visibles.

Mettre en forme du texte avec les tags

Un tag est un nom associé à une portion de texte. Il peut modifier la couleur, la police ou l’arrière-plan sans changer le contenu lui-même. C’est ce mécanisme qui permet de mélanger du texte normal, des avertissements et des titres dans une seule zone.

import tkinter as tk

fenetre = tk.Tk()
zone = tk.Text(fenetre, width=70, height=12)
zone.pack(padx=12, pady=12)

zone.tag_configure(
    "titre",
    font=("Arial", 14, "bold"),
    foreground="#174a7e"
)
zone.tag_configure(
    "alerte",
    foreground="#a00020",
    background="#ffe5e5"
)

zone.insert("1.0", "Journal de l’application\n", "titre")
zone.insert("end", "Connexion établie.\n")
zone.insert("end", "Attention : fichier introuvable.", "alerte")

fenetre.mainloop()

On peut aussi appliquer un tag après l’insertion avec tag_add(). Cette méthode est utile pour un surligneur, un moteur de recherche ou une coloration syntaxique simple.

zone.tag_add("alerte", "3.0", "3.end")

Rechercher une occurrence

La méthode search() renvoie l’index de la prochaine occurrence trouvée. Le code suivant parcourt le contenu et met en évidence chaque apparition du mot recherché.

def surligner_mot(mot):
    zone.tag_remove("alerte", "1.0", "end")
    debut = "1.0"

    while True:
        position = zone.search(mot, debut, stopindex="end-1c", nocase=True)
        if not position:
            break

        fin = f"{position}+{len(mot)}c"
        zone.tag_add("alerte", position, fin)
        debut = fin

Le tag ne remplace pas une véritable coloration syntaxique pour un langage complexe, mais il suffit pour un journal d’événements, un outil de recherche ou un éditeur de configuration léger. Pour un gros fichier source, je déconseille de rescanner tout le contenu à chaque frappe, car l’interface peut perdre en fluidité.

Ajouter une barre de défilement et des raccourcis

Une zone Text devient rapidement inconfortable sans défilement. Le branchement doit être fait dans les deux sens, avec yscrollcommand du côté de Text et command du côté de la barre.

import tkinter as tk

fenetre = tk.Tk()
fenetre.geometry("700x450")

cadre = tk.Frame(fenetre)
cadre.pack(fill="both", expand=True)

zone = tk.Text(cadre, wrap="word", undo=True)
barre = tk.Scrollbar(cadre, orient="vertical", command=zone.yview)

zone.configure(yscrollcommand=barre.set)

zone.pack(side="left", fill="both", expand=True)
barre.pack(side="right", fill="y")

fenetre.mainloop()

Pour aller plus vite, le module tkinter.scrolledtext fournit une variante déjà équipée d’une barre verticale. Elle réduit le code, mais offre moins de contrôle sur la disposition si l’interface devient plus élaborée.

from tkinter.scrolledtext import ScrolledText

zone = ScrolledText(fenetre, wrap="word", undo=True)
zone.pack(fill="both", expand=True)

Les événements personnalisés sont utiles pour les fonctions métier. Par exemple, peut déclencher une sauvegarde, tandis que peut ouvrir une recherche. Une fonction liée à un événement reçoit toujours un objet événement.

def sauvegarder_raccourci(event=None):
    contenu = zone.get("1.0", "end-1c")
    with open("notes.txt", "w", encoding="utf-8") as fichier:
        fichier.write(contenu)

fenetre.bind("", sauvegarder_raccourci)

Sauvegarder le contenu sans piège

Le widget ne sauvegarde rien automatiquement. Il faut extraire la chaîne, choisir un encodage et gérer les erreurs d’accès au fichier. Pour du texte français, utf-8 doit être le choix par défaut, car il conserve correctement les accents et les caractères spéciaux.

import tkinter as tk
from tkinter import filedialog, messagebox

def enregistrer():
    chemin = filedialog.asksaveasfilename(
        defaultextension=".txt",
        filetypes=[("Fichiers texte", "*.txt"), ("Tous les fichiers", "*.*")]
    )

    if not chemin:
        return

    try:
        contenu = zone.get("1.0", "end-1c")
        with open(chemin, "w", encoding="utf-8") as fichier:
            fichier.write(contenu)
    except OSError as erreur:
        messagebox.showerror("Erreur", f"Impossible d'enregistrer le fichier : {erreur}")

Dans une application réelle, j’ajoute aussi un indicateur de modification non enregistrée. Le point important est de ne pas confondre le contenu affiché avec le fichier sur le disque. Tant que l’utilisateur n’a pas lancé l’enregistrement, ces deux états peuvent être différents.

Éviter les erreurs les plus fréquentes

Utiliser le mauvais widget

Text ne remplace pas toujours Entry. Si le programme attend une valeur courte, une seule ligne et une validation immédiate, Entry sera plus simple à exploiter. Choisir Text uniquement parce qu’il est plus grand ajoute souvent une gestion inutile des index et des retours à la ligne.

Oublier que les index sont spécifiques

Un index comme 2.4 n’est pas un index Python classique. Il représente une position dans la structure interne de Tkinter. Les expressions telles que "insert", "end-1c", "sel.first" ou "2.end" sont souvent plus lisibles que des calculs manuels.

Lire aussi : Exécuter un script Python - La méthode robuste et sans erreur

Modifier une zone désactivée

Avec state="disabled", les appels à insert() et delete() sont bloqués. Pour mettre à jour le contenu, il faut temporairement réactiver le widget, effectuer la modification, puis le désactiver à nouveau.

zone.configure(state="normal")
zone.delete("1.0", "end")
zone.insert("1.0", "Contenu actualisé")
zone.configure(state="disabled")

Enfin, évitez de créer un nouveau widget à chaque clic pour afficher des résultats. Réutiliser la même zone, la vider puis la remplir est plus léger et conserve mieux la sélection, le défilement et la logique de l’interface.

Une base solide pour vos interfaces Python

Pour commencer, retenez ce trio simple. Créez un widget Text avec une disposition extensible, utilisez insert(), get() et delete() pour le contenu, puis ajoutez les tags et le défilement seulement lorsque l’application en a réellement besoin.

La vraie force de ce composant ne vient pas de sa taille, mais de sa combinaison entre édition multiligne, index précis, recherche et mise en forme. Pour un bloc-notes, un afficheur de logs ou un petit éditeur Python, cette base reste simple, fiable et suffisamment flexible pour évoluer sans réécrire toute l’interface.

Questions fréquentes

Entry convient aux valeurs courtes sur une seule ligne, comme un nom ou une adresse e-mail. Text est conçu pour les contenus multilingues, comme les notes, commentaires, journaux ou fichiers source.
L’index end inclut le saut de ligne final ajouté automatiquement par Tkinter. Utilisez zone.get("1.0", "end-1c") pour récupérer le contenu réel sans ce caractère supplémentaire, notamment avant une sauvegarde ou une comparaison.
Définissez des tags avec tag_configure(), puis associez-les au texte lors de l’insertion avec insert() ou après coup avec tag_add(). Un tag peut modifier la police, la couleur du texte ou l’arrière-plan, par exemple pour distinguer un titre ou une alerte.
Créez une Scrollbar, reliez-la au widget avec command=zone.yview, puis configurez yscrollcommand=barre.set sur la zone Text. Pour une solution plus rapide, ScrolledText du module tkinter.scrolledtext inclut déjà une barre verticale.
Évaluer l'article

Moyenne: 0.0 / 5 · 0 évaluations

Tags

sauvegarde tkinter text défilement
Autor Alfred Jacques
Alfred Jacques
Je m'appelle Alfred Jacques et j'ai accumulé 12 ans d'expérience dans le domaine des technologies, en particulier dans les secteurs du web, de l'intelligence artificielle, des réseaux et de la sécurité. Mon intérêt pour ces sujets a débuté dès mon adolescence, lorsque j'ai découvert les possibilités infinies qu'offrent les nouvelles technologies. J'aime explorer les enjeux complexes de ces domaines et partager des informations claires et accessibles pour aider mes lecteurs à mieux comprendre les défis et les évolutions technologiques. Dans mes écrits, je m'efforce de fournir des analyses précises et à jour, en vérifiant mes sources et en comparant différentes perspectives. Je m'engage à simplifier des concepts parfois difficiles afin de rendre l'information utile et compréhensible pour tous. Que ce soit en suivant les dernières tendances ou en organisant mes connaissances de manière claire, je souhaite que mes articles soient une ressource précieuse pour ceux qui s'intéressent à la technologie et à ses implications dans notre quotidien.
Commentaires (0)
Ajouter un commentaire