Attribut d'instance d'une classe à l'autre

Fermé
Morebutter Messages postés 5 Date d'inscription lundi 11 juillet 2022 Statut Membre Dernière intervention 13 juillet 2022 - 11 juil. 2022 à 10:28
Morebutter Messages postés 5 Date d'inscription lundi 11 juillet 2022 Statut Membre Dernière intervention 13 juillet 2022 - 13 juil. 2022 à 07:39

Bonjour,

J'ai un petit souci d'accès à un attribut d'instance d'une classe A à partir d'une classe B (je suis newbie sur Python).

En l'occurrence, je voudrais avoir accès à self.source et self.dest généré dans le construct de la class Instance tout cela à partir de la class Main_Frame. Ce serait possible de m'éclairer svp? Merci par avance :).

Ps : ici mon but est de garder mes boutons transfert dans la frame contenant la scrollbar tout en faisant en sorte que lorsque j'appuie sur n'importe quel bouton transfert, ce dernier doit m'afficher le contenu des entries correspondantes.

Ici je vois bien que dans 'command = ' cela ne doit pas pointer vers self. Mais plutot vers une méthode de la class instance. 

Mais c'est le serpent qui se mort la queue j'ai l'impression...

from tkinter import *
 
class ScrollableCanvas(Frame):
     def __init__(self, parent):
        Frame.__init__(self, parent)
         
        canvas=Canvas(self,bg='#FFFFFF',width=300,height=300,scrollregion=(0,0,500,500))
  
        vbar=Scrollbar(self,orient=VERTICAL)
        vbar.pack(side=RIGHT, fill=Y)
        vbar.config(command=canvas.yview)
         
        canvas.config(width=200,height=200)
        canvas.config(yscrollcommand=vbar.set)
        canvas.pack(side=LEFT,expand=True,fill=BOTH)
         
        # create a frame inside the canvas which will be scrolled with it
        self.interior = interior = Frame(canvas)
        interior_id = canvas.create_window(0, 0, window=interior, anchor=NW )
 
        # track changes to the canvas and frame width and sync them,
        # also updating the scrollbar
        def _configure_interior(event):
            # update the scrollbars to match the size of the inner frame
            size = (interior.winfo_reqwidth(), interior.winfo_reqheight())
            canvas.config(scrollregion="0 0 %s %s" % size)
            if interior.winfo_reqwidth() != canvas.winfo_width():
                # update the canvas's width to fit the inner frame
                canvas.config(width=interior.winfo_reqwidth())
        interior.bind('<Configure>', _configure_interior)
 
        def _configure_canvas(event):
            if interior.winfo_reqwidth() != canvas.winfo_width():
                # update the inner frame's width to fill the canvas
                canvas.itemconfigure(interior_id, width=canvas.winfo_width())
        canvas.bind('<Configure>', _configure_canvas)


    
class Instance():
    decal = 0
    def __init__(self, source , dest, transf):
        
        self.source = source
        self.dest = dest
        self.transf = transf
     
        self.decal = Instance.decal
      
        
        
        self.source.grid(row = self.decal, column = 1)
        self.dest.grid(row = self.decal, column = 2)
        self.transf.grid(row = self.decal, column = 3 )



        
        Instance.decal += 1 
        print(self.decal)

   
    

 

class Main_frame(Frame):
    
    # Init
    def __init__(self, fenetre_principale=None):

       
        Frame.__init__(self, fenetre_principale)
        
      
        self.grid()

    
        self.scrollable_canvas = ScrollableCanvas(self)
        self.scrollable_canvas.grid(row=1,column=3)

        self.decal = 2
        self.ajout()
        
        


        
    def ajout(self):
        self.buajout = Button(self, text = "Ajout", command = self.add_entries).grid(row=1,column=0)



    def get_source_dest(self):
        
        print(self.source.get(), self.dest.get())
    





    def add_entries(self):

        
        Instance(Entry(self.scrollable_canvas.interior, relief=RIDGE,width=15,bg='white'), Entry(self.scrollable_canvas.interior, relief=RIDGE,width=15,bg='white'), Button(self.scrollable_canvas.interior, text = "Transférer", command= self.get_source_dest))######c'est là que ça coince########
          
        
        


            
  
  
if __name__ == "__main__":
    root = Tk()
    root.title("tk")
    interface = Main_frame(fenetre_principale=root)
    interface.mainloop()

Si vous avez une idée de comment je peux me sortir de cette impasse ce serait gentil. Merci par avance :)
Windows / Chrome 103.0.0.0

4 réponses

yg_be Messages postés 22773 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 9 mai 2024 1 481
11 juil. 2022 à 11:30

bonjour,

Deux suggestions:

  • éviter d'utiliser "Instance" comme nom de classe
  • commencer par des exercices beaucoup plus simples 
1
yg_be Messages postés 22773 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 9 mai 2024 1 481
11 juil. 2022 à 12:10

Autre suggestion:

    def add_entries(self):
        btn=Button(self.scrollable_canvas.interior, text = "Transférer")
        newI=Instance(Entry(self.scrollable_canvas.interior, relief=RIDGE,width=15,bg='white'),
                   Entry(self.scrollable_canvas.interior, relief=RIDGE,width=15,bg='white'),
                   btn)
        btn['command']=newI.get_source_dest
1
yg_be Messages postés 22773 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 9 mai 2024 1 481 > yg_be Messages postés 22773 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 9 mai 2024
Modifié le 11 juil. 2022 à 12:21

Plus simple, ne pas spécifier "command=" dans add_entries(), et le faire dans __init__ de la classe Instance:

transf['command']=self.get_source_dest
1
Morebutter Messages postés 5 Date d'inscription lundi 11 juillet 2022 Statut Membre Dernière intervention 13 juillet 2022 1 > yg_be Messages postés 22773 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 9 mai 2024
12 juil. 2022 à 02:33

Hello,

Merci c'est exactement ce que je cherchais. Je savais que le serpent ne pouvait pas se mordre la queue comme ça mais je ne savais pas trop comment jouer avec les arguments de la class Button. Mais ca me rassure. Merci d'avoir contribuer à ma quête de compréhension même si c'est rien pour vous c'est beaucoup pour moi. A++++

1
yg_be Messages postés 22773 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 9 mai 2024 1 481 > Morebutter Messages postés 5 Date d'inscription lundi 11 juillet 2022 Statut Membre Dernière intervention 13 juillet 2022
12 juil. 2022 à 09:20

Peux-tu alors marquer la discussion comme résolue?

0
yg_be Messages postés 22773 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 9 mai 2024 1 481
11 juil. 2022 à 12:56

S'il n'avait pas été possible d'ainsi modifier a posteriori la commande du bouton, tu aurais pu faire ainsi:

class memt:
    def getget(self):
        memt.trf.get_source_dest()

class Main_frame(Frame):
    def add_entries(self):
        newtrf=memt()
        newtrf.trf=Instance(Entry(self.scrollable_canvas.interior, relief=RIDGE,width=15,bg='white'),
                 Entry(self.scrollable_canvas.interior, relief=RIDGE,width=15,bg='white'),
                 Button(self.scrollable_canvas.interior, text = "Transférer",
                        command=newtrf.getget))
1
corneille_grivoise
11 juil. 2022 à 13:33

Bonjour, si tu veux qu'une classe B partage les mêmes attributs, méthodes qu'une classe A, ben c'est ce qu'on fait avec l'héritage non ? Python supporte le multi-héritage, donc pas de problème à ce que ta classe hérite à la fois de Frame et Instance. Sinon d'accord avec au-dessus pour utiliser simplement un attribut pour stocker l'objet Instance.

Mais tu devrais décrire succinctement ce qu'est censé faire ton script, peut-être qu'il y a moyen de faire cela d'une autre/meilleure façon.

1
Whismeril Messages postés 19040 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 9 mai 2024 932
11 juil. 2022 à 15:54

Bonjour corneille grivoise.

Je crois, en lisant la question de Morebutter, qu'il (elle?) n'a pas compris ce qu'est un objet.

Par exemple le fair d'appeler sa classe Instance, tend à démontrer qu'il n'a pas trop d'idée de ce que cela veut dire.

L'héritage se reposant sur le socle bien acquis de ce qu'est un objet, pas sûr que ton intervention soit à propos à ce stade de sa formation.

Loin de moi l'intention de brimer ton ardeur à aider, mais il faut penser au fait que ce qui est évident pour toi n'est peut-être pas encore imaginable par le demandeur.

C'est un peu comme essayer d'expliquer les puissances à quelqu'un qui débute l'addition.


En plus, il me semble qu'yg_be répond à son besoin

1
Morebutter Messages postés 5 Date d'inscription lundi 11 juillet 2022 Statut Membre Dernière intervention 13 juillet 2022 1 > Whismeril Messages postés 19040 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 9 mai 2024
12 juil. 2022 à 02:53

Hello, je suis complètement d'accord avec toi sur le fait que je n'ai pas tout compris de la programmation OO et que ce qui est évident pour certains ne l'est pas forcément pour moi. Cela s'explique par le fait que je sois newbie dans cette exercice comme je l'ai précisé sur mon post initial ^^.

Concernant aux méthodes d'apprentissages. Chaque cerveau à la sienne. Et la mienne est assez bizarre je le conçois lol. J'ai l'air de mettre la charrue avant les boeufs et de vouloir aller plus vite que la musique. Mais le truc, c'est que j'ai tendance à me poser des questions trop à l'avance de mon apprentissage et j'ai souvent envi de connaitre la réponse tout de suite. Alors que effectivement, si j'avais la patience de suivre la chose étape par étape cela m'aurait paru évident de pouvoir isoler 'command' de la class Button. Par exemple là, après avoir eu vos réponses, je vais retourner dans mon apprentissage step by step. Et peut-être que demain j'aurai une autre question trop en avance et ainsi de suite. lol

Heureusement que je n'ai pas ce mode de raisonnement quand je mate un film sinon je me serai spoil à chaque fois ^^

0
Whismeril Messages postés 19040 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 9 mai 2024 932 > Morebutter Messages postés 5 Date d'inscription lundi 11 juillet 2022 Statut Membre Dernière intervention 13 juillet 2022
Modifié le 12 juil. 2022 à 07:30

Non en fait c'est un comportement assez courant, et je crois, amplifié ces dernières années par un fait général le "tout tout de suite et maintenant".

Ca tient en même temps

  • de la curiosité et ça c'est une bonne chose 
  • de l'impatience, ça c'est pas vraiment une bonne chose car il y a des principes et des concepts qui nécessitent qu'on s'y attarde
  • parfois de la surestime de soi, voir de l'orgueil et dans ce cas c'est une mauvaise chose, car in finit toujours par se casser les dents.

Tu vois le mec qui veut monter un meuble en kit ou une hotte aspirante sans lire notice, il va s'en sortir jusqu'à un point de blocage 

  • le curieux va admettre avoir été présomptueux, lire la notice, se rendre compte d'avoir oublié ou mal fait un truc plusieurs étapes auparavant, démonter et refaire correctement
  • l'impatient va insister un moment et quand il finira par se dire qu'il est à 2 doigts de casser un truc va à contre coeur lire la notice et ensuite pester que ce truc est nul à monter et qu'à cause de ça il vient de perdre du temps
  • l'orgueilleux ne s'arrêtera qu'après avoir cassé quelque chose.

En programmation, l'étape de casse totale existe mais elle est rare, donc l'orgueilleux  persiste dans son erreur et la traine comme un boulet dans ton son projet. Pire il la reproduit dans le projet suivant.

Et je sais de quoi je parle, j'ai eu ma dose d'orgueil à mon époque. Et quand j'ai fini par admettre que j'avais mal conçu le coeur du projet (par ce que j'avais sauté des étapes dans mon auto formation) et qu'il fallait tout recommencer à zéro, ça faisait plus d'un an que je bossais dessus.

Si j'avais pris une semaine ou deux pour apprendre les fondamentaux, mon projet aurait été fini correctement en 6 mois.... C'est le temps qu'il m'a fallu la deuxième fois.

2
Morebutter Messages postés 5 Date d'inscription lundi 11 juillet 2022 Statut Membre Dernière intervention 13 juillet 2022 1 > Whismeril Messages postés 19040 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 9 mai 2024
13 juil. 2022 à 07:39

Merci pour ton témoignage vraiment! Ca me rassure du coup. Je vais tacher d'écouter tes conseils et d'essayer de les appliquer surtout à l'avenir. Merci beaucoup!

0
Morebutter Messages postés 5 Date d'inscription lundi 11 juillet 2022 Statut Membre Dernière intervention 13 juillet 2022 1
11 juil. 2022 à 11:54

Bonjour, allez on remplace Instance par Transfert. 

Peu importe la difficulté de l'exercice, ma question est simple :  je demande juste si c'est possible de faire reconnaitre un attribut d'instance d'une class A dans une class B. Ou bien utilisé la méthode d'une class A dans une class B. Je peux pas être plus clair lol

0
yg_be Messages postés 22773 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 9 mai 2024 1 481
11 juil. 2022 à 12:40

A partir d'une instance B1 de classe B, tu peux obtenir un attribut d'une instance A1 de classe A, il suffit d'écrire "A1.attribut".
Dans mon premier exemple: "newI.get_source_dest".

1