Créez une Calculatrice Python Graphique avec Tkinter

Créez une Calculatrice Python Graphique avec Tkinter

Bienvenue sur ce tutoriel où nous allons créer une calculatrice graphique en Python avec Tkinter. Préparez-vous à devenir un pro de Tkinter tout en vous amusant ! 😄✨

🚀 Qu’allons-nous apprendre ?

  1. Créer une interface graphique (GUI) avec Tkinter.
  2. Ajouter des boutons pour les chiffres et les opérations mathématiques.
  3. Gérer les événements clavier (ex. : appuyer sur « Entrée » pour calculer).
  4. Ajouter des fonctionnalités avancées comme le carré et la racine carrée. ✅

🛠️ Avant de commencer

Voici ce dont vous avez besoin :

  • Python 3.7 ou plus : Tkinter est inclus dans Python, donc pas besoin de l’installer !
  • Un éditeur de code : VS Code, PyCharm, ou simplement l’éditeur IDLE de Python.

Astuce : Si vous débutez avec Python, n’hésitez pas à consulter nos autres tutoriels sur LM-Code pour vous familiariser avec les bases. 😉


🧩 Étape 1 : Mise en place du projet

🔍 Qu’est-ce que Tkinter ?

Tkinter est une bibliothèque intégrée à Python qui permet de créer des interfaces graphiques (GUI). Grâce à Tkinter, vous pouvez concevoir des fenêtres, des boutons, des labels, et bien plus encore !

🌟 Initialisation de la fenêtre

On commence par créer une classe Calculatrice pour regrouper toute la logique de notre 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

🎨 Étape 2 : Personnaliser l’apparence

Pour rendre notre calculatrice attrayante, ajoutons des couleurs et des polices. 🌈

# 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

🎯 Pourquoi ces couleurs ?

Elles sont choisies pour rendre l’interface agréable à l’œil. Vous pouvez les personnaliser selon vos goûts ! 🎨


🖥️ Étape 3 : Créer l’affichage

L’affichage se compose de deux parties :

  1. Expression totale : La série complète d’opérations que l’utilisateur a saisie.
  2. Expression actuelle : Ce qui est en cours de saisie (chiffre ou opérateur).

🖼️ Création du cadre d’affichage

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

🖋️ Ajout des étiquettes pour les 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

Astuce : L’attribut anchor=tk.E aligne le texte à droite, comme dans une vraie calculatrice. 🧭


🔢 Étape 4 : Ajouter des boutons pour les chiffres

Chaque bouton est positionné dans une grille grâce à 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)

➕ Étape 5 : Ajouter les opérations mathématiques

Ajoutons les boutons pour les opérations (addition, soustraction, etc.).

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

🔄 Étape 6 : Fonctions spéciales (Clear, Égal)

🧽 Effacer tout (C)

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

✔️ Calculer (=)

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()

🎉 Résultat final

Une calculatrice complète avec :

  • Boutons de chiffres et d’opérateurs.
  • Affichage clair des expressions.
  • Fonctionnalités comme le carré et la racine carrée. 💡

🎁 Bonus : Personnalisation

Ajoutez des fonctionnalités comme :

  • Mode sombre 🌙.
  • Animations de boutons 💫.
  • Thèmes personnalisés pour les couleurs.

Je vous réserve la suite de ce code personnalisé dans un prochain tutoriel sur Python

🎉 Si vous avez des questions, laissez un commentaire ou partagez vos créations avec la communauté. 😊✨

👉 Et maintenant ? Copiez le code ci-dessous et testez le🐍

# 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()

Vous pouvez aussi téléchargez le code complet et mise à jour sur notre dépot Github.

Bon code !

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 *