Ce qui suit est la structure générale de mon programme tkinter python typique.
def funA():
def funA1():
def funA12():
# stuff
def funA2():
# stuff
def funB():
def funB1():
# stuff
def funB2():
# stuff
def funC():
def funC1():
# stuff
def funC2():
# stuff
root = tk.Tk()
button1 = tk.Button(root, command=funA)
button1.pack()
button2 = tk.Button(root, command=funB)
button2.pack()
button3 = tk.Button(root, command=funC)
button3.pack()
funA
funB
et funC
fera apparaître une autre Toplevel
fenêtre avec des widgets lorsque l'utilisateur cliquera sur le bouton 1, 2, 3.
Je me demande si c'est la bonne façon d'écrire un programme python tkinter? Bien sûr, cela fonctionnera même si j'écris de cette façon, mais est-ce le meilleur moyen? Cela semble stupide mais quand je vois les codes écrits par d'autres personnes, leur code n'est pas foiré avec un tas de fonctions et la plupart ont des classes.
Y a-t-il une structure spécifique que nous devrions suivre comme bonne pratique? Comment dois-je planifier avant de commencer à écrire un programme python?
Je sais qu'il n'existe pas de meilleure pratique en matière de programmation et je ne la demande pas non plus. Je veux juste quelques conseils et explications pour me garder dans la bonne direction alors que j'apprends Python par moi-même.
Réponses:
Je préconise une approche orientée objet. Voici le modèle avec lequel je commence:
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:
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.la source
parent
, à moins que vous ne l' utilisiez plus tard. Je ne l'ai pas sauvegardé car aucun des codes de mon exemple n'exigeait qu'il soit sauvegardé.Le fait de placer chacune de vos fenêtres de niveau supérieur dans sa propre classe distincte vous permet de réutiliser le code et d'une meilleure organisation du code. Tous les boutons et méthodes pertinentes présents dans la fenêtre doivent être définis dans cette classe. Voici un exemple (tiré d' ici ):
Regarde aussi:
J'espère que cela pourra aider.
la source
Ce n'est pas une mauvaise structure; cela fonctionnera très bien. Cependant, vous devez avoir des fonctions dans une fonction pour exécuter des commandes lorsque quelqu'un clique sur un bouton ou quelque chose
Donc, ce que vous pouvez faire est d'écrire des classes pour ceux-ci, puis d'avoir des méthodes dans la classe qui gèrent les commandes pour les clics de bouton et autres.
Voici un exemple:
Habituellement, les programmes tk avec plusieurs fenêtres sont de plusieurs grandes classes et dans le
__init__
toutes les entrées, les étiquettes, etc. sont créées, puis chaque méthode consiste à gérer les événements de clic de boutonIl n'y a pas vraiment de bonne façon de le faire, tout ce qui fonctionne pour vous et fait le travail du moment qu'il est lisible et vous pouvez facilement l'expliquer car si vous ne pouvez pas facilement expliquer votre programme, il y a probablement une meilleure façon de le faire .
Jetez un œil à Penser à Tkinter .
la source
La POO doit être l'approche et
frame
doit être une variable de classe au lieu d' une variable d' instance .Référence: http://www.python-course.eu/tkinter_buttons.php
la source
TKinter
sur Python 2. Je recommanderais d'utilisertkinter
pour Python 3. Je placerais également les trois dernières lignes de code sous unemain()
fonction et l'appellerais à la fin du programme. J'éviterais certainement de l' utiliserfrom module_name import *
car il pollue l'espace de noms global et peut réduire la lisibilité.button1 = tk.Button(root, command=funA)
etbutton1 = ttk.Button(root, command=funA)
si letkinter
module d'extension était également importé? Avec la*
syntaxe, les deux lignes de code semblent êtrebutton1 = Button(root, command=funA)
. Je ne recommanderais pas d'utiliser cette syntaxe.L'organisation de votre application à l'aide de la classe facilite le débogage des problèmes et l'amélioration de l'application pour vous et les autres personnes qui travaillent avec vous.
Vous pouvez facilement organiser votre application comme ceci:
la source
La meilleure façon d'apprendre à structurer votre programme est probablement de lire le code d'autres personnes, surtout s'il s'agit d'un grand programme auquel de nombreuses personnes ont contribué. Après avoir examiné le code de nombreux projets, vous devriez avoir une idée de ce que devrait être le style de consensus.
Python, en tant que langage, est spécial en ce sens qu'il existe des directives strictes sur la façon dont vous devez formater votre code. Le premier est le soi-disant "Zen of Python":
Sur un plan plus pratique, il y a PEP8 , le guide de style pour Python.
Dans cet esprit, je dirais que votre style de code ne convient pas vraiment, en particulier les fonctions imbriquées. Trouvez un moyen de les aplatir, soit en utilisant des classes, soit en les déplaçant dans des modules séparés. Cela rendra la structure de votre programme beaucoup plus facile à comprendre.
la source
Personnellement, je n'utilise pas l'approche orientée objet, principalement parce qu'elle a) ne fait que gêner; b) vous ne réutiliserez jamais cela en tant que module.
mais quelque chose qui n'est pas discuté ici, c'est que vous devez utiliser le threading ou le multiprocessing. Toujours. sinon votre application sera horrible.
faites simplement un test simple: lancez une fenêtre, puis récupérez une URL ou autre chose. les modifications sont que votre interface utilisateur ne sera pas mise à jour pendant la demande réseau. Cela signifie que la fenêtre de votre application sera cassée. dépend du système d'exploitation sur lequel vous vous trouvez, mais la plupart du temps, il ne sera pas redessiné, tout ce que vous faites glisser sur la fenêtre sera collé dessus, jusqu'à ce que le processus revienne à la boucle principale TK.
la source