Dans ce tutoriel, tu vas créer une calculatrice Python avec Tkinter : une vraie application de bureau avec écran, boutons, opérations, carré, racine carrée et raccourcis clavier. Le projet idéal pour découvrir les interfaces graphiques en Python et la programmation orientée objet.

Niveau : débutantDurée : ~1 hPython 3 · TkinterCode source gratuit
Calculatrice Python avec Tkinter : interface graphique avec écran et boutons
Le résultat final : une calculatrice graphique en Python avec Tkinter

Ce que tu vas construire : une calculatrice Python avec Tkinter

Une calculatrice est le projet parfait pour débuter avec les interfaces graphiques : tu vas manipuler des fenêtres, des boutons et des événements, tout en structurant ton code dans une classe.

🖥️ Interface graphiqueUne fenêtre avec un écran à deux lignes et une grille de boutons.
➕ OpérationsAddition, soustraction, multiplication et division.
√ Fonctions avancéesCarré (x²) et racine carrée (√x) en un clic.
⌨️ ClavierChiffres, opérateurs et touche Entrée pour calculer.

Prérequis

  • Python 3.7 ou plus : Tkinter est inclus avec Python, rien à installer
  • Un éditeur de code : VS Code, PyCharm ou simplement IDLE
  • Les bases de Python : variables, fonctions et dictionnaires
💡
Bon réflexe

Avant de commencer, crée un environnement dédié à ton projet : suis le guide comment créer un environnement virtuel Python.

Étape 1 : mettre en place le projet

Tkinter est la bibliothèque graphique intégrée à Python : elle permet de créer des fenêtres, des boutons, des textes et bien plus. On commence par une classe Calculatrice qui regroupe toute la logique de l’application :

import tkinter as tk

class Calculatrice:
    def __init__(self):
        self.window = tk.Tk()  # Création de la fenêtre principale
        self.window.geometry("700x700")  # Taille de la fenêtre
        self.window.resizable(0, 0)  # Empêche le redimensionnement
        self.window.title("LM-Code Calculatrice")  # Titre de la fenêtre
calculatrice.py

Étape 2 : personnaliser l’apparence

Définis les polices et les couleurs dans des constantes, en haut du fichier. Tu pourras ainsi changer tout le thème de ta calculatrice Python en modifiant quelques lignes :

# Polices
LARGE_FONT_STYLE = ("Arial", 40, "bold")
SMALL_FONT_STYLE = ("Arial", 16)
DIGITS_FONT_STYLE = ("Arial", 24, "bold")
DEFAULT_FONT_STYLE = ("Arial", 20)

# Couleurs
couleur_symbole = "#eafaf1"  # Boutons des symboles
couleur_chiffre = "#ffffff"  # Boutons des chiffres
couleur_egal = "#abebc6"     # Bouton égal
couleur_ecran = "#ebedef"    # Écran d'affichage
couleur_label_ap = "#25265e" # Texte sur les boutons
calculatrice.py

Étape 3 : créer l’écran d’affichage

L’écran se compose de deux lignes : l’expression totale (le calcul complet saisi) et l’expression actuelle (ce que tu es en train de taper). On crée d’abord le cadre :

def create_display_frame(self):
    frame = tk.Frame(self.window, height=221, bg=couleur_ecran)
    frame.pack(expand=True, fill="both")
    return frame
calculatrice.py

Puis les deux étiquettes de texte :

def create_display_labels(self):
    total_label = tk.Label(self.display_frame, text=self.total_expression, anchor=tk.E, bg=couleur_ecran,
                           fg=couleur_label_ap, padx=24, font=SMALL_FONT_STYLE)
    total_label.pack(expand=True, fill='both')

    label = tk.Label(self.display_frame, text=self.current_expression, anchor=tk.E, bg=couleur_ecran,
                     fg=couleur_label_ap, padx=24, font=LARGE_FONT_STYLE)
    label.pack(expand=True, fill='both')

    return total_label, label
calculatrice.py
ℹ️
Astuce

L’option anchor=tk.E aligne le texte à droite (E pour East), comme sur une vraie calculatrice.

Étape 4 : ajouter les boutons des chiffres

Chaque chiffre est associé à sa position dans la grille (ligne, colonne). Une boucle crée ensuite les boutons et les place avec grid(row, column) :

self.digits = {
    7: (1, 1), 8: (1, 2), 9: (1, 3),
    4: (2, 1), 5: (2, 2), 6: (2, 3),
    1: (3, 1), 2: (3, 2), 3: (3, 3),
    0: (4, 2), '.': (4, 1)
}

def create_digit_buttons(self):
    for digit, grid_value in self.digits.items():
        button = tk.Button(self.buttons_frame, text=str(digit), bg=couleur_chiffre, fg=couleur_label_ap,
                           font=DIGITS_FONT_STYLE, borderwidth=0,
                           command=lambda x=digit: self.add_to_expression(x))
        button.grid(row=grid_value[0], column=grid_value[1], sticky=tk.NSEW)
calculatrice.py

Étape 5 : ajouter les opérations

Les opérateurs sont stockés dans un dictionnaire : la clé est le symbole Python (*, /…) et la valeur est le symbole affiché (×, ÷…) :

self.operations = {"/": "\u00F7", "*": "\u00D7", "-": "-", "+": "+"}

def create_operator_buttons(self):
    i = 0
    for operator, symbol in self.operations.items():
        button = tk.Button(self.buttons_frame, text=symbol, bg=couleur_symbole, fg=couleur_label_ap,
                           font=DEFAULT_FONT_STYLE, borderwidth=0,
                           command=lambda x=operator: self.append_operator(x))
        button.grid(row=i, column=4, sticky=tk.NSEW)
        i += 1
calculatrice.py

Étape 6 : effacer et calculer

Tout effacer (C)

def clear(self):
    self.current_expression = ""
    self.total_expression = ""
    self.update_label()
    self.update_total_label()
calculatrice.py

Calculer le résultat (=)

def evaluate(self):
    self.total_expression += self.current_expression
    try:
        self.current_expression = str(eval(self.total_expression))
        self.total_expression = ""
    except Exception:
        self.current_expression = "Erreur"
    finally:
        self.update_label()
calculatrice.py
⚠️
À propos de eval()

La calculatrice utilise eval() pour calculer l’expression. C’est pratique ici, car seuls les boutons et touches prévus peuvent écrire dans l’expression, mais n’utilise jamais eval() sur un texte saisi librement par un utilisateur.

Le code complet de la calculatrice Python

Voici le programme complet, avec en plus les boutons carré et racine carrée et les raccourcis clavier (chiffres, opérateurs et touche Entrée). Copie-le dans un fichier calculatrice.py, puis lance-le avec python calculatrice.py :

# Importation des modules nécessaires
import tkinter as tk
from tkinter import PhotoImage
from PIL import Image, ImageTk

# Définition des styles de police pour l'interface
LARGE_FONT_STYLE = ("Arial", 40, "bold")
SMALL_FONT_STYLE = ("Arial", 16)
DIGITS_FONT_STYLE = ("Arial", 24, "bold")
DEFAULT_FONT_STYLE = ("Arial", 20)

# Définition des couleurs utilisées dans l'interface
couleur_symbole = "#eafaf1"
couleur_chiffre = "#ffffff"
couleur_egal = "#abebc6"
couleur_ecran = "#ebedef"
couleur_label_ap = "#25265e"

# Classe principale de la calculatrice
class Calculatrice:
    def __init__(self):
        # Création de la fenêtre principale
        self.window = tk.Tk()
        self.window.geometry("700x700")
        self.window.resizable(0, 0)
        self.window.title("LM-Code Calculatrice")
        
        # Ajout d'une icône pour la fenêtre principale
        self.window.iconbitmap("logo.ico")
        
        # Initialisation des variables pour les expressions
        self.total_expression = ""
        self.current_expression = ""
        
        # Création du cadre pour afficher les expressions
        self.display_frame = self.create_display_frame()
        
        # Création des étiquettes pour afficher les expressions
        self.total_label, self.label = self.create_display_labels()
        
        # Définition des boutons pour les chiffres et les opérations
        self.digits = {
            7: (1, 1), 8: (1, 2), 9: (1, 3),
            4: (2, 1), 5: (2, 2), 6: (2, 3),
            1: (3, 1), 2: (3, 2), 3: (3, 3),
            0: (4, 2), '.': (4, 1)
        }
        self.operations = {"/": "\u00F7", "*": "\u00D7", "-": "-", "+": "+"}
        
        # Création du cadre pour les boutons
        self.buttons_frame = self.create_buttons_frame()

        # Configuration des lignes et des colonnes pour les boutons
        self.buttons_frame.rowconfigure(0, weight=1)
        for x in range(1, 5):
            self.buttons_frame.rowconfigure(x, weight=1)
            self.buttons_frame.columnconfigure(x, weight=1)
        
        # Création des boutons pour les chiffres et les opérations
        self.create_digit_buttons()
        self.create_operator_buttons()
        self.create_special_buttons()
        
        # Liaison des touches du clavier aux fonctions correspondantes
        self.bind_keys()

    # Méthode pour lier certaines touches du clavier aux fonctions de la calculatrice
    def bind_keys(self):
        # Touche Entrée pour évaluer l'expression
        self.window.bind("<Return>", lambda event: self.evaluate())
        
        # Liaison des touches des chiffres aux méthodes pour les ajouter à l'expression en cours
        for key in self.digits:
            self.window.bind(str(key), lambda event, digit=key: self.add_to_expression(digit))

        # Liaison des touches des opérations aux méthodes pour les ajouter à l'expression en cours
        for key in self.operations:
            self.window.bind(key, lambda event, operator=key: self.append_operator(operator))

    # Méthode pour créer les boutons spéciaux (Clear, Equals, Square, Square Root)
    def create_special_buttons(self):
        self.create_clear_button()
        self.create_equals_button()
        self.create_square_button()
        self.create_sqrt_button()

    # Méthode pour créer les étiquettes d'affichage des expressions
    def create_display_labels(self):
        total_label = tk.Label(self.display_frame, text=self.total_expression, anchor=tk.E, bg=couleur_ecran ,
                               fg=couleur_label_ap, padx=24, font=SMALL_FONT_STYLE)
        total_label.pack(expand=True, fill='both')

        label = tk.Label(self.display_frame, text=self.current_expression, anchor=tk.E, bg=couleur_ecran ,
                         fg=couleur_label_ap, padx=24, font=LARGE_FONT_STYLE)
        label.pack(expand=True, fill='both')

        return total_label, label

    # Méthode pour créer le cadre d'affichage des expressions
    def create_display_frame(self):
        frame = tk.Frame(self.window, height=221, bg=couleur_ecran )
        frame.pack(expand=True, fill="both")
        return frame

    # Méthode pour ajouter un chiffre ou un point à l'expression en cours
    def add_to_expression(self, value):
        self.current_expression += str(value)
        self.update_label()

    # Méthode pour créer les boutons pour les chiffres et les points
    def create_digit_buttons(self):
        for digit, grid_value in self.digits.items():
            button = tk.Button(self.buttons_frame, text=str(digit), bg=couleur_chiffre, fg=couleur_label_ap, font=DIGITS_FONT_STYLE,
                               borderwidth=0, command=lambda x=digit: self.add_to_expression(x))
            button.grid(row=grid_value[0], column=grid_value[1], sticky=tk.NSEW)

    # Méthode pour ajouter un opérateur à l'expression en cours
    def append_operator(self, operator):
        self.current_expression += operator
        self.total_expression += self.current_expression
        self.current_expression = ""
        self.update_total_label()
        self.update_label()

    # Méthode pour créer les boutons pour les opérations
    def create_operator_buttons(self):
        i = 0
        for operator, symbol in self.operations.items():
            button = tk.Button(self.buttons_frame, text=symbol, bg=couleur_symbole, fg=couleur_label_ap, font=DEFAULT_FONT_STYLE,
                               borderwidth=0, command=lambda x=operator: self.append_operator(x))
            button.grid(row=i, column=4, sticky=tk.NSEW)
            i += 1

    # Méthode pour effacer l'expression en cours et l'expression totale
    def clear(self):
        self.current_expression = ""
        self.total_expression = ""
        self.update_label()
        self.update_total_label()

    # Méthode pour créer le bouton "Clear"
    def create_clear_button(self):
        button = tk.Button(self.buttons_frame, text="C", bg=couleur_symbole, fg=couleur_label_ap, font=DEFAULT_FONT_STYLE,
                           borderwidth=0, command=self.clear)
        button.grid(row=0, column=1, sticky=tk.NSEW)

    # Méthode pour calculer le carré de l'expression en cours
    def square(self):
        self.current_expression = str(eval(f"{self.current_expression}**2"))
        self.update_label()

    # Méthode pour créer le bouton "Square"
    def create_square_button(self):
        button = tk.Button(self.buttons_frame, text="x\u00b2", bg=couleur_symbole, fg=couleur_label_ap, font=DEFAULT_FONT_STYLE,
                           borderwidth=0, command=self.square)
        button.grid(row=0, column=2, sticky=tk.NSEW)

    # Méthode pour calculer la racine carrée de l'expression en cours
    def sqrt(self):
        self.current_expression = str(eval(f"{self.current_expression}**0.5"))
        self.update_label()

    # Méthode pour créer le bouton "Square Root"
    def create_sqrt_button(self):
        button = tk.Button(self.buttons_frame, text="\u221ax", bg=couleur_symbole, fg=couleur_label_ap, font=DEFAULT_FONT_STYLE,
                           borderwidth=0, command=self.sqrt)
        button.grid(row=0, column=3, sticky=tk.NSEW)

    # Méthode pour évaluer l'expression totale
    def evaluate(self):
        self.total_expression += self.current_expression
        self.update_total_label()
        try:
            self.current_expression = str(eval(self.total_expression))
            self.total_expression = ""
        except Exception as e:
            self.current_expression = "Error"
        finally:
            self.update_label()

    # Méthode pour créer le bouton "Equals" pour évaluer l'expression
    def create_equals_button(self):
        button = tk.Button(self.buttons_frame, text="=", bg=couleur_egal, fg=couleur_label_ap, font=DEFAULT_FONT_STYLE,
                           borderwidth=0, command=self.evaluate)
        button.grid(row=4, column=3, columnspan=2, sticky=tk.NSEW)

    # Méthode pour créer le cadre des boutons
    def create_buttons_frame(self):
        frame = tk.Frame(self.window)
        frame.pack(expand=True, fill="both")
        return frame

    # Méthode pour mettre à jour l'étiquette d'affichage de l'expression totale
    def update_total_label(self):
        expression = self.total_expression
        for operator, symbol in self.operations.items():
            expression = expression.replace(operator, f' {symbol} ')
        self.total_label.config(text=expression)

    # Méthode pour mettre à jour l'étiquette d'affichage de l'expression en cours
    def update_label(self):
        self.label.config(text=self.current_expression[:11])

    # Méthode pour lancer la boucle principale de l'interface graphique
    def run(self):
        self.window.mainloop()

# Point d'entrée du programme
if __name__ == "__main__":
    calc = Calculatrice()
    calc.run()
calculatrice.py

Aller plus loin

FAQ : questions fréquentes

Faut-il installer Tkinter ?

Non, Tkinter est inclus avec Python sur Windows et macOS. Sur certaines distributions Linux, installe-le avec sudo apt install python3-tk.

Pourquoi ma calculatrice affiche « Error » ?

Le message s’affiche quand l’expression est invalide, par exemple une division par zéro ou deux opérateurs à la suite. Le calcul est protégé par un bloc try/except.

Comment changer les couleurs de la calculatrice ?

Modifie les constantes de couleur définies en haut du fichier (fond, boutons, texte) : toute l’interface se met à jour automatiquement.

Puis-je transformer ma calculatrice en fichier .exe ?

Oui, avec PyInstaller : installe-le avec pip install pyinstaller, puis lance pyinstaller –onefile –windowed calculatrice.py.

Bravo, ta calculatrice Python avec Tkinter est terminée ! Tu sais maintenant créer une interface graphique, gérer des boutons et des événements clavier. Partage tes créations ou tes questions en commentaire !

Comments

No comments yet. Why don’t you start the discussion?

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *