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 :

Design pattern Factory et TKinter


Sujet :

Tkinter Python

  1. #1
    Membre du Club
    Homme Profil pro
    Medecin Biologiste
    Inscrit en
    janvier 2013
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Medecin Biologiste
    Secteur : Santé

    Informations forums :
    Inscription : janvier 2013
    Messages : 63
    Points : 49
    Points
    49
    Par défaut Design pattern Factory et TKinter
    Bonjour,
    J'essaye de mettre dans un pattern MVC, un pattern Factory dans la View. Se soldant par un échec, j'ai décidé d'utiliser un code minimal, donc de ne faire qu'une View avec un pattern Factory. Mais voilà c'est toujours un echec. Pouvez vous me donner un petit coup de main. En attente de vous lire. Par avance sincères remerciements.

    Mon code qui n'est pas parfait...:
    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
    import tkinter as tk
     
    class View():
        def __init__(self):
            super().__init__()
     
        def mavue(self,n):
            p=Factory.create(n)
            p.output()
     
    class View1:
        def output(self):
            pass
     
    class Intro(View1):
        def output(self):
            print('-----Coucou c est l intro ')
            self.btn = tk.Button(self, text="Hello!",
                                 command=self.say_hello)
            self.btn.pack(padx=120, pady=30)
     
     
    class Vuetravail(View1):
        def output(self):
            print('-----En plein travail...')
            self.btn = tk.Button(self, text="au travail!",
                                 command=self.say_hello)
            self.btn.pack(padx=120, pady=30)
     
     
    class Fintravail(View1):
        def output(self):
            print('-----Coucou c est la fin!!!')
            self.btn = tk.Button(self, text="Fin!",
                                 command=self.say_hello)
            self.btn.pack(padx=120, pady=30)
     
     
    class Factory():
        @staticmethod
        def create(type):
            p=None
            if (type == 0):
                p=Intro()
            else:
                if (type==1):
                    p=Vuetravail()
                else :
                    p=Fintravail()
            return p
     
     
    if __name__ == "__main__":
        root=tk.Tk()
        app = View(root)
        app.mainloop()

  2. #2
    Membre éprouvé
    Avatar de Hominidé
    Homme Profil pro
    Paysan à 3 francs six sous
    Inscrit en
    juin 2018
    Messages
    743
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Paysan à 3 francs six sous
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : juin 2018
    Messages : 743
    Points : 1 282
    Points
    1 282
    Billets dans le blog
    3
    Par défaut
    Bonjour,
    j'ignore ce qu'est un pattern MVC..., mais en tapant 'tkinter MVC' sur mon moteur de recherche, je constate la présence de nombreuses réponses!
    Tu les as consultées?
    pathlib, poetry, importlib_ressources...

  3. #3
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    juin 2008
    Messages
    19 924
    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 : 19 924
    Points : 34 473
    Points
    34 473
    Par défaut
    Citation Envoyé par johanndebutant Voir le message
    Mais voilà c'est toujours un echec. Pouvez vous me donner un petit coup de main.
    Si vous exécutez ce code, il devrait planter avec un message d'erreur à comprendre pour corriger.

    Et cette démarche là, écrire du code, se planter, comprendre l'erreur (et le message qui va avec s'il y a) et corriger, c'est juste le boulot de base qu'on doit maîtriser avant de se lancer dans l'aventure des patterns.

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

  4. #4
    Membre du Club
    Homme Profil pro
    Medecin Biologiste
    Inscrit en
    janvier 2013
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Medecin Biologiste
    Secteur : Santé

    Informations forums :
    Inscription : janvier 2013
    Messages : 63
    Points : 49
    Points
    49
    Par défaut J ai une solution...
    Bonjour,
    Merci pour vos réponses. En suivant vos conseils j'ai un code qui marche, mais vu que c'est la première fois que je fais du pattern factory, j'aimerai avoir votre avis sur la cohérence de mon code car je ne sais pas si c'est vraiment très "propre"...
    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
    import tkinter as tk
     
     
    class View(tk.Frame):
        def mavue(self, n):
            self.parent = tk.Frame()
            self.n=n
            p = Factory.create(self.n,self.parent)
            p.output()
     
        def say_hello(self):
            pass
     
    class View1(tk.Frame):
        def output(self):
            pass
     
        def say_hello(self):
            pass
     
    class Intro(View1):
        def output(self):
            print('-----Coucou c est l intro ')
            self.parent=tk.Frame()
            self.btn = tk.Button(self.parent, text="Click Intro!", command=self.say_hello)
            self.btn.pack(padx=120, pady=30)
            self.parent.pack()
     
     
    class Vuetravail(View1):
        def output(self):
            print('-----En plein travail...')
            self.parent = tk.Frame()
            self.btn = tk.Button(self.parent, text="Click Travail!", command=self.say_hello)
            self.btn.pack(padx=120, pady=30)
            self.parent.pack()
     
     
    class Fintravail(View1):
        def output(self):
            print('-----Coucou c est la fin!!!')
            self.parent = tk.Frame()
            self.btn = tk.Button(self.parent, text="Click Fin!", command=self.say_hello)
            self.btn.pack(padx=120, pady=30)
            self.parent.pack()
     
     
    class Factory():
        @staticmethod
        def create(type,parent):
            p = None
            parent=parent
            if (type == 0):
                p = Intro(parent)
            else:
                if (type == 1):
                    p = Vuetravail(parent)
                else:
                    p = Fintravail(parent)
            return p
     
     
    if __name__ == "__main__":
        root=tk.Tk()
        app = View(root)
        app.mavue(0)
        root.mainloop()
    En vous remerciant pour vos remarques.

  5. #5
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    juin 2008
    Messages
    19 924
    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 : 19 924
    Points : 34 473
    Points
    34 473
    Par défaut
    Salut,

    Citation Envoyé par johanndebutant Voir le message
    j'aimerai avoir votre avis sur la cohérence de mon code car je ne sais pas si c'est vraiment très "propre"...
    L'intérêt d'une factory/fabrique, c'est de fabriquer... et si elle ne fabrique qu'un seul objet: bof.
    N'oubliez pas que les patterns c'est d'abord un outil de communication entre développeurs => il y a une histoire à raconter (le problème à résoudre et la solution apportée par le pattern) avant de montrer le code qui l'illustre.

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

  6. #6
    Membre du Club
    Homme Profil pro
    Medecin Biologiste
    Inscrit en
    janvier 2013
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Medecin Biologiste
    Secteur : Santé

    Informations forums :
    Inscription : janvier 2013
    Messages : 63
    Points : 49
    Points
    49
    Par défaut
    Merci beaucoup pour votre aide. En effet j'ai créé un import View dans lequel j ai mis mes différentes vue sous forme de classes. Ca marche plutôt très bien et ça permet de garder une bonne visibilité du code.
    Encore sincères remerciements

  7. #7
    Membre du Club
    Homme Profil pro
    Medecin Biologiste
    Inscrit en
    janvier 2013
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Medecin Biologiste
    Secteur : Santé

    Informations forums :
    Inscription : janvier 2013
    Messages : 63
    Points : 49
    Points
    49
    Par défaut Encore un soucis dessus
    En essayant mon code minimal avec la gestion d'un bouton ça ne marche pas quand je clique sur le bouton en effet il me réclame un self dans la méthode gestion . En java j'aurais géré avec des Getter mais là ça ne marche pas . En regardant ce qui se fait j'ai essayé avec @property mais pareil... alors si vous pouviez me donner encore un petit coup de main ...

    voici mes codes minimums , MVC_Strategy1:
    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
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    import tkinter as tk
    import View3
    import time
     
    class Strategy:
        def calculate(self,a,b):
            pass
     
    class Addition(Strategy):
        def calculate(self,a,b):
            return a+b
     
    class Soustraction(Strategy):
        def calculate(self,a,b):
            return a-b
     
    class Model():
        __strategy=None
     
        def __init__(self,strategy):
            self.__strategy=strategy
     
        def do__calculate(self,a,b):
            return self.__strategy.calculate(a,b)
     
    class controller():
        def __init__(self,root):
            #self.m=Model(Soustraction())
            #self.m=Model(Addition())
            self.v=View(root)
            self.v.mavue(0)
            #time.sleep(10)
            #self.v.mavue(1)
     
     
        def gestion(self):
            print("ca marche...")
     
     
    class View(tk.Frame):
        def mavue(self, n):
            self.parent = tk.Frame()
            self.n=n
            p = Factory.create(self.n,self.parent)
            p.output()
     
     
        def say_hello(self):
            pass
     
    class View1(tk.Frame):
        def output(self):
            pass
     
        def say_hello(self):
            pass
     
     
    class Intro(View1):
        def output(self):
            print('-----Coucou c est l intro ')
            self.parent=View3.View01()
     
     
    class Vuetravail(View1):
        def output(self):
            print('-----En plein travail...')
            self.parent=View3.View02()
     
     
     
    class Fintravail(View1):
        def output(self):
            print('-----Coucou c est la fin!!!')
            self.parent=View3.View03()
     
     
    class Factory():
        @staticmethod
        def create(type,parent):
            p = None
            parent=parent
            if (type == 0):
                p = Intro(parent)
            else:
                if (type == 1):
                    p = Vuetravail(parent)
                else:
                    p = Fintravail(parent)
            return p
     
    if __name__ == "__main__":
        root = tk.Tk()
        root.geometry("1200x700")
        app = controller(root)
        root.mainloop()
    et View3.py:
    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
    import tkinter as tk
    from tkinter import *
    import tkinter.ttk as ttk
     
    import MVC_Strategy1
     
    _bgcolor = '#d9d9d9'  # X11 color: 'gray85'
    _fgcolor = '#000000'  # X11 color: 'black'
    _compcolor = 'gray40' # X11 color: #666666
    _ana1color = '#c3c3c3' # Closest X11 color: 'gray76'
    _ana2color = 'beige' # X11 color: #f5f5dc
    _tabfg1 = 'black'
    _tabfg2 = 'black'
    _tabbg1 = 'grey75'
    _tabbg2 = 'grey89'
    _bgmode = 'light'
     
    _style_code_ran = 0
     
    class View01:
        def __init__(self, top=None):
            self.top = top
            self.Button1 = tk.Button(self.top)
            self.Button1.place(relx=0.431, rely=0.201, height=24, width=47)
            self.Button1.configure(activebackground="beige")
            self.Button1.configure(activeforeground="black")
            self.Button1.configure(background="#d9d9d9")
            self.Button1.configure(compound='left')
            self.Button1.configure(disabledforeground="#a3a3a3")
            self.Button1.configure(foreground="#000000")
            self.Button1.configure(highlightbackground="#d9d9d9")
            self.Button1.configure(highlightcolor="black")
            self.Button1.configure(pady="0")
            self.Button1.configure(text='Valider C1',command=MVC_Strategy1.controller.gestion)
     
    class View02:
        def __init__(self, top=None):
            self.top = top
            self.Button1 = tk.Button(self.top)
            self.Button1.place(relx=0.431, rely=0.201, height=24, width=47)
            self.Button1.configure(activebackground="beige")
            self.Button1.configure(activeforeground="black")
            self.Button1.configure(background="#d9d9d9")
            self.Button1.configure(compound='left')
            self.Button1.configure(disabledforeground="#a3a3a3")
            self.Button1.configure(foreground="#000000")
            self.Button1.configure(highlightbackground="#d9d9d9")
            self.Button1.configure(highlightcolor="black")
            self.Button1.configure(pady="0")
            self.Button1.configure(text='Valider C2',command=MVC_Strategy1.controller.gestion)
     
        class View03:
            def __init__(self, top=None):
                self.top = top
                self.Button1 = tk.Button(self.top)
                self.Button1.place(relx=0.431, rely=0.201, height=24, width=47)
                self.Button1.configure(activebackground="beige")
                self.Button1.configure(activeforeground="black")
                self.Button1.configure(background="#d9d9d9")
                self.Button1.configure(compound='left')
                self.Button1.configure(disabledforeground="#a3a3a3")
                self.Button1.configure(foreground="#000000")
                self.Button1.configure(highlightbackground="#d9d9d9")
                self.Button1.configure(highlightcolor="black")
                self.Button1.configure(pady="0")
                self.Button1.configure(text='Valider C3',command=MVC_Strategy1.controller.gestion)
    Par avance sincères remerciements et en attente de vous lire.

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    juin 2008
    Messages
    19 924
    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 : 19 924
    Points : 34 473
    Points
    34 473
    Par défaut
    Citation Envoyé par johanndebutant Voir le message
    En essayant mon code minimal avec la gestion d'un bouton ça ne marche pas quand je clique sur le bouton en effet il me réclame un self dans la méthode gestion
    Appeler la fonction MVC_Strategy1.controller.gestion() suffit à reproduire le problème... et cette fonction là attend effectivement "self" en paramètre.
    Avant de partir à vouloir faire des choses compliquées, il faudrait apprendre à faire simple.

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

  9. #9
    Membre du Club
    Homme Profil pro
    Medecin Biologiste
    Inscrit en
    janvier 2013
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Medecin Biologiste
    Secteur : Santé

    Informations forums :
    Inscription : janvier 2013
    Messages : 63
    Points : 49
    Points
    49
    Par défaut
    Effectivement j'ai rajouté
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    def gestion(self=View3):
    et ça marche.
    Merci pour votre aide

  10. #10
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    juin 2008
    Messages
    19 924
    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 : 19 924
    Points : 34 473
    Points
    34 473
    Par défaut
    Citation Envoyé par johanndebutant Voir le message
    Effectivement j'ai rajouté
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    def gestion(self=View3):
    et ça marche.
    Python se contenterait aussi de def gestion(self=123): ou def gestion():...
    De là à dire que "ça marche"...

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

  11. #11
    Membre habitué
    Profil pro
    Inscrit en
    septembre 2010
    Messages
    121
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : septembre 2010
    Messages : 121
    Points : 197
    Points
    197
    Par défaut
    le self fait référence à une instance d'une classe; là tu sembles vouloir l'utiliser comme une fonction statique (ou comme une méthode de classe).

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

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Alimentation

    Informations forums :
    Inscription : juillet 2006
    Messages : 3 276
    Points : 5 988
    Points
    5 988
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class Strategy:    
        def calculate(self,a,b):
            pass
     
    class Addition(Strategy):
        def calculate(self,a,b):
            return a+b
     
    class Soustraction(Strategy):
        def calculate(self,a,b):         
            return a-b
    En Java ce genre de développement ressemble à une classe abstraite, vous pouvez le faire avec le module abc
    Si vous ne le faîtes pas, vous pourriez instancier Strategy qui n'aurait pas de sens si l'on suit votre conception.

    Une proposition pourrait être,

    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
    import random
    from abc import ABC
    from abc import abstractmethod
     
     
    class Strategy(ABC):
        @abstractmethod
        def calculate(self, a, b):
            raise NotImplemented
     
     
    class Addition(Strategy):
        def calculate(self, a, b):
            return a + b
     
     
    class Soustraction(Strategy):
        def calculate(self, a, b):
            return a - b
     
     
    class Factory:
     
        strategies = {"addition": Addition, "soustraction": Soustraction}
     
        def __init__(self, strategy_name="addition"):
            assert strategy_name in Factory.strategies
            self.__strategy: Strategy = Factory.strategies[strategy_name]()
     
        def __call__(self, a, b):
            return self.__strategy.calculate(a, b)
     
     
    obj_list = [
        Factory(random.choice(list(Factory.strategies.keys()))) for _ in range(10)
    ]  # Création de 10 opérateurs
    results = [
        obj(random.randint(1, 100), random.randint(1, 100)) for obj in obj_list
    ]  # Résultats des opérations entre deux nombres aléatoires
    print(results)  # par exemple : [ -8, 173, -68, 82, 50, 0, 80, 186, 191, 108]
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

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

Discussions similaires

  1. design pattern factory
    Par olive_le_malin dans le forum C++
    Réponses: 2
    Dernier message: 23/08/2007, 16h31
  2. Classe + design pattern factory
    Par Rodrigue dans le forum C++
    Réponses: 8
    Dernier message: 07/11/2006, 15h42
  3. [Conception]Design Pattern Factory ?
    Par ®om dans le forum Logging
    Réponses: 8
    Dernier message: 13/09/2006, 11h20
  4. [Fabrique] [Java] Design Pattern Factory
    Par SkyBioSS dans le forum Design Patterns
    Réponses: 3
    Dernier message: 24/05/2006, 15h53

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