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.

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.
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
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êtrecalculatrice.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 boutonscalculatrice.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 framecalculatrice.pyPuis 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, labelcalculatrice.pyL’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 += 1calculatrice.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.pyCalculer 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.pyLa 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.pyAller plus loin
- Ajouter un mode sombre en changeant les constantes de couleur
- Ajouter des animations au survol des boutons avec les événements
<Enter>et<Leave> - Ajouter un historique des derniers calculs
- Créer un exécutable Windows avec
pyinstaller --onefile calculatrice.py - Continuer avec Tkinter : générateur de mots de passe, lecteur MP3 ou jeu de dames
- Comparer avec la version web : calculatrice en HTML, CSS et JavaScript
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 !

