IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Tkinter Python Discussion :

maître/esclave ou parent/enfant ?


Sujet :

Tkinter Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé Avatar de Pierrot92320
    Homme Profil pro
    Ingénieur en retraite (électronique)
    Inscrit en
    Avril 2009
    Messages
    159
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Cher (Centre)

    Informations professionnelles :
    Activité : Ingénieur en retraite (électronique)
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2009
    Messages : 159
    Par défaut maître/esclave ou parent/enfant ?
    Bonjour

    Ce post n'est pas une question mais le fruit de mes réflexions, que j'offre à ceux que cela peut intéresser (donc aux débutants). Je me suis largement inspiré des informations précieuses données par wiztricks un peu plus bas sur ce forum. Tout est contenu dans les commentaires deux petits scripts suivants. Le premier parle des notions maître/esclave et parent/enfant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    from tkinter import *
    app = Tk()
    app.geometry('160x130+10+10')
     
    frame = Frame(app, name = 'frame', bg='pink')
     
    bouton1 = Button(frame, name='bouton1', bg='yellow')
     
    bouton2 = Button(app, name='bouton2', text='Bouton2')
     
    message = Label(frame, text='maître/esclave \nou parent/enfant ?')
     
    frame.pack(padx=20)
    bouton1.pack()
    bouton2.pack(in_=bouton1, padx=10, pady=10)
    message.pack(padx=10, pady=10)
     
    print('app =', app)
    print('app.children =', app.children)
    print('bouton2.master =', bouton2.master)
     
    print('\nbouton1 =', bouton1)
    print('bouton1.master =', bouton1.master)
    print('bouton2 =', bouton2)
     
    print('\nid(message) =', id(message))
    print('messsage =', message)
     
    """
    La notion parent/enfant (parent/child) de tkinter n'a rien avoir avec celle
    concernant l'héritage dans le langage python.
     
    Les termes parent/enfant et maître/esclave (master/slave) de tkinter sont
    généralement utilisés de manière synonyme dans la littérature que l'on trouve
    sur internet. Pourtant, dans la documentation tkinter, il semble qu'il y ait
    une distinction assez claire :
     - parent/enfant signifie 'widget conteneur'/'widget contenu' au sens visuel.
     - maître/esclave a le même sens mais concerne le geometry manager.
     
    Le 'widget contenu' est le même dans les deux cas. L'esclave est donc toujours
    l'enfant. Par contre, le maître est parfois un conteneur lui-même contenu dans
    le parent.
     
    Dans l'instruction < bouton2 = Button(app, ...) >, l'argument 'app' désigne le
    widget 'parent' dans lequel sera contenu, au sens visuel du terme, le widget
    'enfant' bouton2. On peut vérifier cela en tapant dans la console :
     - print(app)            : renvoie -> '.' qui désigne la racine
     - print(app.children)   : renvoie -> frame ainsi que bouton2
     - print(bouton2.master) : renvoie -> app
     
    Le nom 'master' est un choix maladroit pour désigner l'attribut. Il aurait été
    plus judicieux de l'appeler 'bouton2.parent'. Cette maladresse est probablement
    la cause du mélange des termes que l'on constate dans la littérature internet.
     
    Par défaut, le geometry manager utilise le parent indiqué dans l'instruction
    < bouton2 = Button(app, ...) > comme étant le widget 'master' pour le packing,
    c'est à dire app dans cet exemple. Mais ici ce n'est pas le cas à cause de
    l'instruction bouton2.pack(in_=bouton1, ...) qui désigne bouton1 comme le
    master. On peut vérifier cela en tapant dans la console :
     - bouton2.pack_info()   : renvoie -> bouton1 (comme master)
     - bouton1.pack_slaves() : renvoie -> bouton2 (comme esclave)
     
    Le master désigné par l'option 'in_' ne peut être que le parent (valeur par
    défaut) ou un enfant du parent. La conséquence de cette restriction est que le
    parent reste toujours le conteneur global, et que les méthodes parent.destroy() et
    master.destroy() provoquent toutes deux la destruction du widget ainsi packé.
     
    REMARQUE :
    La relation parent/enfant est utilisée par tkinter pour construire les noms des
    widgets et organiser leur hiérarchie graphique par des 'paths', un peu à la
    manière des répertoires/sous-répertoires. On peut voir cela en tapant dans la
    console :
     - print(bouton1)        : renvoie -> '.frame.bouton1'
     - print(bouton1.master) : renvoie -> '.frame'
     - print(bouton2)        : renvoie -> '.bouton2'
     
    Si aucun nom n'est donné au widget au moment de son instanciation par l'option
    'name', tkinter fabrique le nom à l'aide de l' id. On peut voir cela en tapant
    dans la console :
     - id(message)  : renvoie -> xxxxxxxx
     - str(message) : renvoie -> '.frame.xxxxxxxx'
    """
    Le second vous pose une petite colle (que j'ai mis très longtemps à résoudre) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    from tkinter import *
     
    class MonBouton(Frame):
        def __init__(self, boss, nom, text):
            Frame.__init__(self, boss=None, name='cadre')
            self.bou = Button(self, name=nom, text=text)
            self.bou.pack()
     
    class Application (Frame):
        def __init__(self):        
            Frame.__init__(self, name='frame')
            self.pack()
     
            self.bouton1 = Button(self, name='bt1', text='Bouton 1')
            self.bouton1.pack()
     
            self.bouton2 = MonBouton(self, nom='bt2', text='Bouton 2')
            self.bouton2.pack()
     
    app = Application()
     
     
     
    print('app =', app)
    print('app.master =', app.master)
    print('\napp.bouton1 =', app.bouton1)
    print('app.bouton2 =', app.bouton2)
    print('\napp.bouton2.children =', app.bouton2.children)
    print('app.bouton2.bou =', app.bouton2.bou)
    print('\napp.master.pack_slaves =', app.master.pack_slaves())
    print('\napp.pack_slaves =', app.pack_slaves())
     
    #app.mainloop()
     
    """
    Dans ce programme, app est une frame, enfant de la fenêtre racine nommée <.>
     
    Les widgets app.bouton1 et app.bouton2 sont des attributs de app car ils ont
    été tous deux instanciés dans la définition de classe de app. Le premier est un
    objet de la classe Button() et le second un objet de la classe MonBouton().
     
    Les informations dans la console montrent que :
     - Le nom app.bouton1 est <.frame.bt1>, c'est donc un enfant de app
     - Le nom de app.bouton2 est <.cadre> (voir l(explications plus bas), c'est
       donc un enfant de la fenêtre racine.
     
    **** Comment faire pour que les boutons soient tous deux enfants de app ? *****
    *******        (il suffit de modifier la valeur d'un argument)         ********
     
    Réponse :
     
    app.bouton1 est enfant de app car, dans son instanciation en ligne 14,
    l'argument self représente app.
     
    app.bouton2, malgré son apparence visuelle, est une frame car la classe
    MonBouton est dérivée d'une frame nommée 'cadre'. Celle-ci est particulière en
    ce sens qu'elle contient un widget de la classe Button, nommé 'bou'.
     
    Si on veut que le widget app.bouton2 soit enfant de frame (comme app.bouton1),
    il faut supprimer la valeur None en ligne 5, de manière à transmettre au
    constructeur de la classe parente la référence de frame. Faute de quoi l'objet
    app.bouton2 s'instancie par défaut dans la fenêtre racine.
    """
    Bonne réussite

  2. #2
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 075
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 075
    Par défaut
    Bonjour,

    Je dirais que vous avez une façon de penser bien différente de la mienne

    Vous avez l'air de faire une fixette sur la syntaxe, alors que le conception avec des framework tel que tkinter, wxPython, ... me semble bien plus important !

    Ce que je vois dans votre 2ème exemple (la petite colle), c'est une Frame composée d'un Button et une autre Frame, d'ailleurs vous êtes vicieux !!!

    Vous faites croire en appelant votre classe MonBouton, que l'on a à faire à un objet Button, mais non, c'est bien à une Frame que l'on a à faire...
    Vous faites croire que la classe Application est un objet Tk, mais non, c'est bien à une Frame que l'on a à faire...

    Attention à rendre vos noms de classe, fonction et attribut de telle sorte qu'elle soit lisible et qu'elle ne mette pas dans le doute la compréhension de votre code. C'est surtout pour cela que votre explication devient complexe et cela abusément, alors qu'il n'en n'est rien si on respecte des conventions de nommage correctes.

    Sur le principe je pense que vous tendez à essayer de faire comprendre l'héritage, mais je peux me tromper ?

    Bonne continuation...

Discussions similaires

  1. Problème requête parent/enfant
    Par Bobtop dans le forum Requêtes
    Réponses: 2
    Dernier message: 30/05/2006, 13h07
  2. [.Net] Echange formulaire parents enfants
    Par Arnaud Malabeux dans le forum C++/CLI
    Réponses: 4
    Dernier message: 15/05/2006, 07h59
  3. [.net] Fenêtres parent/enfant
    Par akrodev dans le forum MFC
    Réponses: 1
    Dernier message: 14/04/2006, 23h54
  4. [D7,ORACLE] : maître / esclave et modif d'un DataSet
    Par Magnus dans le forum Bases de données
    Réponses: 4
    Dernier message: 27/04/2005, 09h29
  5. [VB.NET] Problème liste Parent-Enfant dans DataGrid
    Par vonbier dans le forum ASP.NET
    Réponses: 7
    Dernier message: 27/01/2005, 08h53

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo