Je préconise une approche orientée objet. Voici le modèle avec lequel je commence:
# Use Tkinter for python 2, tkinter for python 3
import tkinter as tk
class MainApplication(tk.Frame):
def __init__(self, parent, *args, **kwargs):
tk.Frame.__init__(self, parent, *args, **kwargs)
self.parent = parent
<create the rest of your GUI here>
if __name__ == "__main__":
root = tk.Tk()
MainApplication(root).pack(side="top", fill="both", expand=True)
root.mainloop()
Les choses importantes à noter sont:
Je n'utilise pas d'importation générique. J'importe le package en tant que "tk", ce qui nécessite que je préfixe toutes les commandes avec tk.
. Cela évite la pollution globale des espaces de noms, et rend le code complètement évident lorsque vous utilisez des classes Tkinter, des classes ttk ou certaines des vôtres.
L'application principale est une classe . Cela vous donne un espace de noms privé pour tous vos rappels et fonctions privées, et facilite généralement l'organisation de votre code. Dans un style procédural, vous devez coder de haut en bas, définir les fonctions avant de les utiliser, etc. Avec cette méthode, vous ne le faites pas puisque vous ne créez réellement la fenêtre principale qu'à la toute dernière étape. Je préfère hériter de tk.Frame
juste parce que je commence généralement par créer un cadre, mais ce n'est en aucun cas nécessaire.
Si votre application a des fenêtres de niveau supérieur supplémentaires, je vous recommande de faire de chacune de celles-ci une classe distincte, héritant de tk.Toplevel
. Cela vous donne tous les mêmes avantages mentionnés ci-dessus - les fenêtres sont atomiques, elles ont leur propre espace de noms et le code est bien organisé. De plus, il est facile de mettre chacun dans son propre module une fois que le code commence à devenir volumineux.
Enfin, vous voudrez peut-être envisager d'utiliser des classes pour chaque partie majeure de votre interface. Par exemple, si vous créez une application avec une barre d'outils, un volet de navigation, une barre d'état et une zone principale, vous pouvez créer chacune de ces classes. Cela rend votre code principal assez petit et facile à comprendre:
class Navbar(tk.Frame): ...
class Toolbar(tk.Frame): ...
class Statusbar(tk.Frame): ...
class Main(tk.Frame): ...
class MainApplication(tk.Frame):
def __init__(self, parent, *args, **kwargs):
tk.Frame.__init__(self, parent, *args, **kwargs)
self.statusbar = Statusbar(self, ...)
self.toolbar = Toolbar(self, ...)
self.navbar = Navbar(self, ...)
self.main = Main(self, ...)
self.statusbar.pack(side="bottom", fill="x")
self.toolbar.pack(side="top", fill="x")
self.navbar.pack(side="left", fill="y")
self.main.pack(side="right", fill="both", expand=True)
Puisque toutes ces instances partagent un parent commun, le parent devient effectivement la partie «contrôleur» d'une architecture modèle-vue-contrôleur. Ainsi, par exemple, la fenêtre principale pourrait placer quelque chose sur la barre d'état en appelant self.parent.statusbar.set("Hello, world")
. Cela vous permet de définir une interface simple entre les composants, contribuant à maintenir le couplage à un minimum.