OUJOOD.COM
Un script Python unique suffit pour une petite application. Dès qu'on dépasse quelques centaines de lignes ou qu'on veut réutiliser des parties du code ailleurs, répartir le projet en fichiers séparés devient une nécessité. La structure décrite ici est minimaliste mais suffisante pour la majorité des projets Tkinter de taille moyenne.
Structure de base recommandée
Voici une organisation typique pour une application Tkinter de taille moyenne :
mon_application/ │ ├── main.py # point d'entrée — lance l'application ├── app.py # classe Application principale (hérite de tk.Tk) │ ├── vues/ # les écrans / panneaux de l'interface │ ├── __init__.py │ ├── vue_principale.py │ └── vue_parametres.py │ ├── logique/ # traitement des données, sans aucun import tkinter │ ├── __init__.py │ └── traitement.py │ └── ressources/ # images, icônes, fichiers de données └── icone.png
La règle la plus importante : le dossier logique/ ne doit contenir aucun import Tkinter. La logique métier — calculs, lecture de fichiers, traitement de données — doit pouvoir tourner indépendamment de l'interface. Cela facilite les tests et permet de remplacer Tkinter par une autre interface (web, CLI) sans retoucher la logique.
main.py — point d'entrée
# main.py
from app import Application
if __name__ == "__main__":
app = Application()
app.mainloop()
main.py est volontairement minimal. Sa seule responsabilité : importer et lancer. Le garde if __name__ == "__main__" empêche le lancement automatique si ce fichier est importé par un autre module.
app.py — classe principale
# app.py
import tkinter as tk
from tkinter import messagebox
from vues.vue_principale import VuePrincipale
from vues.vue_parametres import VueParametres
class Application(tk.Tk):
def __init__(self):
super().__init__()
self.title("Mon application")
self.geometry("600x400")
self.protocol("WM_DELETE_WINDOW", self._quitter)
self._vue_active = None
self._afficher_vue(VuePrincipale)
def _afficher_vue(self, classe_vue):
if self._vue_active:
self._vue_active.destroy()
self._vue_active = classe_vue(self)
self._vue_active.pack(fill="both", expand=True)
def aller_parametres(self):
self._afficher_vue(VueParametres)
def aller_principale(self):
self._afficher_vue(VuePrincipale)
def _quitter(self):
if messagebox.askokcancel("Quitter", "Fermer l'application ?"):
self.destroy()
vues/vue_principale.py — un écran
# vues/vue_principale.py import tkinter as tk from logique.traitement import calculer_total class VuePrincipale(tk.Frame): def __init__(self, parent): super().__init__(parent) self._parent = parent self._creer_widgets() def _creer_widgets(self): tk.Label(self, text="Vue principale", font=("Arial", 14, "bold")).pack(pady=20) self.champ = tk.Entry(self, width=20) self.champ.pack() tk.Button(self, text="Calculer", command=self._calculer).pack(pady=8) self.label_res = tk.Label(self, text="") self.label_res.pack() tk.Button(self, text="Paramètres", command=self._parent.aller_parametres).pack(pady=10) def _calculer(self): try: valeur = float(self.champ.get()) resultat = calculer_total(valeur) # appel à la logique self.label_res.config(text=f"Total : {resultat:.2f}") except ValueError: self.label_res.config(text="Valeur invalide")
La vue appelle calculer_total() depuis le module logique — elle ne sait pas comment le calcul est fait, elle reçoit juste le résultat. Pour naviguer vers un autre écran, elle appelle self._parent.aller_parametres() — la vue délègue la navigation à l'application. Ce principe de séparation des responsabilités est la base de toute architecture maintenable, que ce soit avec Tkinter, Pandas ou NumPy en arrière-plan.
Par carabde | Mis à jour le 30 avril 2025