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 :

Héritage de Canvas [Python 3.X]


Sujet :

Tkinter Python

  1. #1
    Membre du Club
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Mai 2018
    Messages
    47
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2018
    Messages : 47
    Points : 40
    Points
    40
    Par défaut Héritage de Canvas
    Bonjour,

    j'aimerais avoir un rectangle en instanciant la classe joueur (c'est pour faire un pong ensuite), mais j'ai NameError: name 'master' is not defined . Je pensais hériter des méthodes et des attributs en self de la classe parente dans ma classe joueur. Bref, ce n'est plus très clair pour moi.

    Il y a quelqu'un temps, wiztricks, pour un autre problème, m'a proposé une amélioration de code utilisant : super().__init__(bg='light yellow',height=500,width=500). Qu'apporte super() ? J'ai du mal à l'utiliser et à comprendre (internet indique que c'est surtout pour de l'héritage multiple). l'emploi de super() doit il être privilégié? ou est ce que je peux m'en passer pour des cas simples ? Quelle est la meilleurs pratique ?

    Dans le tuto oscillo de Swinnen, l'auteur fait une classe en héritant de Canvas également.

    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
     
    from tkinter import *
     
    class Application(Canvas):   
        def __init__(self, master, lar, hau):
            Canvas.__init__(self)                            
            self.configure(width=lar, height=hau, bg="black")  
            self.lar, self.hau = lar, hau
            self.create_line(self.lar/2,0,self.lar/2,self.hau+2,fill="white",width = 5)        
     
    class Joueur(Application):
        def __init__(self):
            Application.__init__(self, master, lar, hau)
            joueur = self.create_rectangle(10,self.lar/2,10,self.lar/2+20,fill="white",width = 5)        
     
    root = Tk()
    launch = Application(root, 600, 300)
    launch.pack()
    joueur_1 = Joueur()
    root.mainloop()
    Merci

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 778
    Points
    36 778
    Par défaut
    Salut,

    Citation Envoyé par Kazvert Voir le message
    j'aimerais avoir un rectangle en instanciant la classe joueur (c'est pour faire un pong ensuite), mais j'ai NameError: name 'master' is not defined . Je pensais hériter des méthodes et des attributs en self de la classe parente dans ma classe joueur. Bref, ce n'est plus très clair pour moi.
    Relisez votre code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    class Joueur(Application):
        def __init__(self):
            Application.__init__(self, master, lar, hau)
    Oubliez les "class" qui vous perturbent et imaginez de simples fonctions genre:
    et posez vous la question de savoir de quel chapeau vont sortir les paramètres d'appel a, b, c de la fonction g?
    Comme ce ne sont pas des variables locales, Python va les chercher dans l'espace de noms globals et s'il ne les trouve pas "NameError" sera la punition.

    Il y a quelqu'un temps, wiztricks, pour un autre problème, m'a proposé une amélioration de code utilisant : super().__init__(bg='light yellow',height=500,width=500). Qu'apporte super() ? J'ai du mal à l'utiliser et à comprendre (internet indique que c'est surtout pour de l'héritage multiple). l'emploi de super() doit il être privilégié? ou est ce que je peux m'en passer pour des cas simples ? Quelle est la meilleurs pratique ?
    super travaille pour vous et permet de passer de:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    class Application(Canvas):   
        def __init__(self, master, lar, hau):
            Canvas.__init__(self)
    à l'écriture:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    class Application(Canvas):   
        def __init__(self, master, lar, hau):
            super().__init__()
    fonctionnellement, c'est la même chose.

    Personnellement, je préfère "super" parce que si Application doit hériter d'une version modifiée du Canvas, il n'y a qu'une ligne à changer. Mais pour débuter, faites comme vous préférez.

    Relisez votre code:
    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
    from tkinter import *
     
    class Application(Canvas):   
        def __init__(self, master, lar, hau):
            Canvas.__init__(self)                            
            self.configure(width=lar, height=hau, bg="black")  
            self.lar, self.hau = lar, hau
            self.create_line(self.lar/2,0,self.lar/2,self.hau+2,fill="white",width = 5)        
     
    class Joueur(Application):
        def __init__(self):
            Application.__init__(self, master, lar, hau)
            joueur = self.create_rectangle(10,self.lar/2,10,self.lar/2+20,fill="white",width = 5)        
     
    root = Tk()
    launch = Application(root, 600, 300)
    launch.pack()
    joueur_1 = Joueur()
    root.mainloop()
    C'est quoi la logique: une application et plusieurs joueurs ou une application et un seul joueur?
    Dans les deux cas, c'est le bazar: joueur hérite d'application, donc créer un joueur crée une nouvelle instance d'application?
    Le joueur aura probablement besoin d'accéder au Canvas/Application pour y dessiner ce qu'il est.
    L'héritage n'est pas la bonne relation: il faut utiliser un agrégat:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    class Joueur(Application):
        def __init__(self, application):
            self.application = application
            self.joueur = application.create_rectangle(10,self.lar/2,10,self.lar/2+20,fill="white",width = 5)
    et passer launch à joueur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    joueur_1 = Joueur(launch)
    note: les différentes relations qu'on peut créer entre classes sont la base de la POO. Python vous permet d'écrire de la POO mais pour apprendre, il faut s'y former (et la POO n'a rien de spécifique à Python) avec des bouquins/tutos comme "les patterns pour les nuls".

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Membre du Club
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Mai 2018
    Messages
    47
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2018
    Messages : 47
    Points : 40
    Points
    40
    Par défaut
    Merci pour la réponse,

    Je comprends mon problème initial, si les paramètres d'appel ne sont pas définis ...

    Au final, j'aimerais effectivement instancier joueur deux fois (ou plus) sans créer une nouvelle instance d'application à chaque fois (ce que je faisais au final) .

    Par contre, en mettant launch en argument de joueur, je ne retrouve pas self.lar . Définir une méthode dans application qui renvoie (avec return) la largeur et la hauteur est elle la bonne façon de faire ?

    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
     
    from tkinter import *
     
    class Application(Canvas):   
        def __init__(self, master, lar, hau):
            super().__init__()                            
            self.configure(width=lar, height=hau, bg="black")  
            self.lar = lar
            self.hau = hau    
            self.create_line(self.lar/2,0,self.lar/2,self.hau+2,fill="white",width = 5)      
        def can_prop(self):
            return (self.lar,self.hau)
     
    class Joueur(Application):
        def __init__(self, application):
            self.application = application
            self.lar = self.application.can_prop()[0]
            self.hau = self.application.can_prop()[1]
            print(self.lar/60)
     
            self.joueur = self.application.create_rectangle(10,self.lar/60,20,20,fill="white",width = 5)
     
    root = Tk()
    launch = Application(root, 600, 300)
    launch.pack()
    joueur_1 = Joueur(launch)
    root.mainloop()

    Je vais regarder des tutoriels sur le design pattern, mon objectif est de bien comprendre la POO. Si le tuto traite de C++, je comprendrai quand même ?

    Bonne soirée

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 778
    Points
    36 778
    Par défaut
    Salut,

    Désolé mais dans ma réponse, j'ai oublié de supprimer l'héritage entre Joueur et Application. Ca ne change pas grand chose dans le fonctionnement de ce bout de code mais çà n'aide pas côté "clarté". Donc on a:
    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
     
    from tkinter import *
     
    class Application(Canvas):   
        def __init__(self, master, lar, hau):
            super().__init__()                            
            self.configure(width=lar, height=hau, bg="black")  
            self.lar = lar
            self.hau = hau    
            self.create_line(self.lar/2,0,self.lar/2,self.hau+2,fill="white",width = 5)      
        def can_prop(self):
            return (self.lar,self.hau)
     
    class Joueur:
        def __init__(self, application):
            self.application = application
            self.lar = self.application.can_prop()[0]
            self.hau = self.application.can_prop()[1]
            print(self.lar/60)
     
            self.joueur = self.application.create_rectangle(10,self.lar/60,20,20,fill="white",width = 5)
     
    root = Tk()
    launch = Application(root, 600, 300)
    launch.pack()
    joueur_1 = Joueur(launch)
    root.mainloop()

    Citation Envoyé par Kazvert Voir le message
    Par contre, en mettant launch en argument de joueur, je ne retrouve pas self.lar
    self.application.can_prop accède à un attribut d'application.
    self.lar accède à un attribut de "self". Pour accéder à celui d'application, il ne faut pas oublier l'indirection self.application.lar

    Citation Envoyé par Kazvert Voir le message
    Définir une méthode dans application qui renvoie (avec return) la largeur et la hauteur est elle la bonne façon de faire ?
    C'est une façon de faire mais vous pouvez aussi accéder aux attributs "lar" et "hau" directement (modulo de ne pas oublier l'indirection).
    Mais relisez votre code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
            self.lar = self.application.can_prop()[0]
            self.hau = self.application.can_prop()[1]
    Pourquoi stocker ces valeurs dans des attributs spécifiques?
    Que se passe-t-il s'ils changent plus tard?
    A mon sens, ce sont des questions bien plus importantes.

    Je vais regarder des tutoriels sur le design pattern, mon objectif est de bien comprendre la POO. Si le tuto traite de C++, je comprendrai quand même ?
    Vous verrez bien. Si C++ vous gène, vous pouvez toujours cherchez des variantes Python sur Internet et voir si çà vous parle plus.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  5. #5
    Membre du Club
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Mai 2018
    Messages
    47
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2018
    Messages : 47
    Points : 40
    Points
    40
    Par défaut
    ok merci pour les conseils

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Timage et Canvas??
    Par vanack dans le forum C++Builder
    Réponses: 4
    Dernier message: 14/04/2007, 11h38
  2. [Postgres] Héritage + Clés
    Par k-reen dans le forum PostgreSQL
    Réponses: 6
    Dernier message: 21/05/2003, 16h37
  3. [Canvas] Listbox, couleur et multiselect
    Par rbag dans le forum Composants VCL
    Réponses: 3
    Dernier message: 25/09/2002, 13h02
  4. Héritage entre Forms
    Par BarBal dans le forum Composants VCL
    Réponses: 7
    Dernier message: 29/08/2002, 17h44
  5. Réponses: 2
    Dernier message: 17/05/2002, 20h37

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