Héritant de Cadre ou non dans un Tkinter application
J'ai vu deux méthodes de base pour la configuration d'un tkinter programme. Est-il une raison de préférer l'un à l'autre?
from Tkinter import *
class Application():
def __init__(self, root, title):
self.root = root
self.root.title(title)
self.label = Label(self.root, text='Hello')
self.label.grid(row=0, column=0)
root = Tk()
app = Application(root, 'Sample App')
root.mainloop()
et
from Tkinter import *
class Application(Frame):
def __init__(self, title, master=None):
Frame.__init__(self, master)
self.grid()
self.master.title(title)
self.label = Label(self, text='Hello')
self.label.grid(row=0, column=0)
app = Application('Sample App')
app.mainloop()
Vous devez vous connecter pour publier un commentaire.
L'option que je préfère* est pour hériter de la classe des Savoirs traditionnels. Je pense qu'il est plus raisonnable de choix depuis la fenêtre n'est, en effet, votre application. Héritant de
Frame
ne pas faire plus de sens pour moi alors hériter deButton
ouCanvas
ouLabel
. Puisque vous ne pouvez avoir qu'une seule racine, il est logique que c'est ce que vous héritez de.Je pense aussi que ça rend le code plus lisible si vous ne l'importation comme
import Tkinter as tk
plutôt quefrom Tkinter import *
. Tous vos appels puis mentionner explicitement letk
module. Je ne le recommande pas pour tous les modules, mais pour moi, il fait sens avec Tkinter.Par exemple:
* Remarque: depuis l'origine de l'écriture de cette réponse, j'ai changé ma position. Maintenant, je préfère hériter de
Frame
plutôt queTk
. Il n'y a pas de réel avantage, d'une façon ou l'autre, c'est plus d'un choix philosophique qu'autre chose. Peu importe, je crois que si vous héritez deFrame
ouTk
, je pense que quel que soit le choix est mieux que le premier exemple dans le code qui hérite de rien.Un léger avantage héritant de
Frame
a plus deTk
est dans le cas où vous souhaitez que votre application pour prendre en charge plusieurs fenêtres identiques. Dans ce cas, héritant deFrame
vous permet de créer la première fenêtre comme un enfant de la racine, et windows supplémentaires comme les enfants des instances deToplevel
. Cependant, j'ai vu très peu de programmes qui jamais ont besoin pour ce faire.Pour plus d'informations sur la façon dont je pense que Tkinter programmes doivent être structurés, voir ma réponse à la question Python Tkinter, la structure du programme.
root
(ou ce que vous appelez) au lieu deself
. Cependant, il n'y a presque jamais une bonne raison de faire une fenêtre de taille fixe. Si un utilisateur veut une fenêtre à être plus grandes ou plus petites, qui sommes-nous (comme l'app designer) pour leur dire le contraire? C'est beaucoup mieux (et tout aussi facile) pour la conception de votre application à avoir un bon comportement de redimensionnement.Frame
, vous devez déplacer cette recommandation vers le haut de votre réponse.Un Cadre est généralement utilisé comme un la géométrie de maître pour les autres widgets.
Depuis que la demande a généralement de nombreux widgets, vous aurez souvent envie de les contenir dans un Cadre, ou au moins utiliser le Cadre pour ajouter un peu de
borderwidth
, rembourrage, ou d'autres finesse.De nombreux exemples extraits que vous pourriez trouver sur le web ne pas utiliser un Cadre parce que
ils veulent juste faire preuve d'une certaine fonction dans le plus court laps de code.
Ainsi, l'utilisation d'une Image si vous en avez besoin, sinon, ne le font pas.
Modifier: je pense que la meilleure façon d'organiser une interface graphique est donnée dans ce Tkinter tutoriel:
simpleApp.py:
C'est principalement comme votre première exemple
SimpleApp
hérite deobject
, pasFrame
. Je pense que c'est mieux que de sous-classementFrame
puisque nous ne sommes pas en remplaçant touteFrame
méthodes. Je préfère penser queSimpleApp
comme ayant unFrame
plutôt que d'être unFrame
.Avoir
SimpleApp
sous-classeobject
a un avantage significatif sur les sous-classementtk.Tk
, cependant: il le rend facile à intégrerSimpleApp
dans un grand app:Ainsi, simpleApp.py peut être un script autonome ainsi qu'une importables module.
Si vous essayez cela avec
SimpleApp
héritant detk.Tk
, vous vous retrouvez avec des extra indésirable windows.Frame
, mais ne sont pas beaucoup de sens. Toutes les images doivent avoir un parent, alors pourquoi ne pas mettre votre application à hériter de la mère de tous les widgets (ie: la fenêtre racine)?self
contreroot
oumaster
ou ce que vous choisissez).tk.Tk
et sans supplément de windows ne s'affiche.Il y a peut être un avantage pour le réglage de votre haut niveau objet d'hériter de
Tk
au lieu deFrame
. L'avantage survient lorsque vous avez élément dynamique à votre interface graphique, par exemple unLabel
dont le contenu que vous souhaitez définir untextvariable=foo
au lieu detext= 'Label text'
.Dans ce cas, il est très utile d'utiliser le
Tkinter.DoubleVar
,Tkinter.IntVar
, etTkinter.StringVar
objets pour stocker les données, depuis l'interface graphique se met à jour automatiquement à chaque fois que ces objets sont définis. Toutefois, pour utiliser ces objets, vous devez spécifier leur maître comme la racineTkinter.Tk()
instance en cours d'exécution. C'est plus facile si vous l'avez explicitement faire de votre objet principal d'être une sous-classe deTkinter.Tk,
alors que de générer des images et des widgets, de sorte que vous pouvez passer le long de laTk
instance et de définir vos variables correctement.Voici un petit programme d'exemple pour illustrer l'idée.